How to get a reference to current module's attributes in Python

前端 未结 3 386
梦毁少年i
梦毁少年i 2020-11-28 04:02

What I\'m trying to do would look like this in the command line:

>>> import mymodule
>>> names = dir(mymodule)

How can I

相关标签:
3条回答
  • 2020-11-28 04:44

    Just use globals()

    globals() — Return a dictionary representing the current global symbol table. This is always the dictionary of the current module (inside a function or method, this is the module where it is defined, not the module from which it is called).

    http://docs.python.org/library/functions.html#globals

    0 讨论(0)
  • 2020-11-28 05:00

    As previously mentioned, globals gives you a dictionary as opposed to dir() which gives you a list of the names defined in the module. The way I typically see this done is like this:

    import sys
    dir(sys.modules[__name__])
    
    0 讨论(0)
  • 2020-11-28 05:00

    It might be late to answer, but I didn't found the correct answer for myself. The most closest and precise solution (faster than inspect.stack()) in the python 3.7.x:

      # search for first module in the stack
      stack_frame = inspect.currentframe()
      while stack_frame:
        print('***', stack_frame.f_code.co_name, stack_frame.f_code.co_filename, stack_frame.f_lineno)
        if stack_frame.f_code.co_name == '<module>':
          if stack_frame.f_code.co_filename != '<stdin>':
            caller_module = inspect.getmodule(stack_frame)
          else:
            # piped or interactive import
            caller_module = sys.modules['__main__']
          if not caller_module is None:
            #... do something here ...
          break
        stack_frame = stack_frame.f_back
    

    Pros:

    • Preciser than globals() method.
    • Does not depend on the stack intermediate frames, which can be added for example, via hooking or by the 3dparty tools like pytest:
    *** foo ... ..
    *** boo ... ..
    *** runtest c:\python\x86\37\lib\site-packages\xonsh\pytest_plugin.py 58
    *** pytest_runtest_call c:\python\x86\37\lib\site-packages\_pytest\runner.py 125
    *** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
    *** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
    *** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
    *** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
    *** <lambda> c:\python\x86\37\lib\site-packages\_pytest\runner.py 201
    *** from_call c:\python\x86\37\lib\site-packages\_pytest\runner.py 229
    *** call_runtest_hook c:\python\x86\37\lib\site-packages\_pytest\runner.py 201
    *** call_and_report c:\python\x86\37\lib\site-packages\_pytest\runner.py 176
    *** runtestprotocol c:\python\x86\37\lib\site-packages\_pytest\runner.py 95
    *** pytest_runtest_protocol c:\python\x86\37\lib\site-packages\_pytest\runner.py 80
    *** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
    *** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
    *** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
    *** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
    *** pytest_runtestloop c:\python\x86\37\lib\site-packages\_pytest\main.py 258
    *** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
    *** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
    *** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
    *** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
    *** _main c:\python\x86\37\lib\site-packages\_pytest\main.py 237
    *** wrap_session c:\python\x86\37\lib\site-packages\_pytest\main.py 193
    *** pytest_cmdline_main c:\python\x86\37\lib\site-packages\_pytest\main.py 230
    *** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
    *** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
    *** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
    *** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
    *** main c:\python\x86\37\lib\site-packages\_pytest\config\__init__.py 90
    *** <module> c:\Python\x86\37\Scripts\pytest.exe\__main__.py 7
    
    • Can handle python piped or interactive session.

    Cons:

    • A kind of much precise and can return modules registered in an executable like for the pytest.exe which might not what you want.
    • inspect.getmodule still may return None on valid modules depending on hooking

    I have an extension to the python: How to import a module given the full path?

    The extension having wrapper functions for that case:

    def tkl_get_stack_frame_module_by_offset(skip_stack_frames = 0, use_last_frame_on_out_of_stack = False):
      ...
    
    def tkl_get_stack_frame_module_by_name(name = '<module>'):
      ...
    

    You have to just initialize the extension properly:

    # portable import to the global space
    sys.path.append(<path-to-tacklelib-module-directory>)
    import tacklelib as tkl
    
    tkl.tkl_init(tkl, global_config = {'log_import_module':os.environ.get('TACKLELIB_LOG_IMPORT_MODULE')})
    
    # cleanup
    del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
    sys.path.pop()
    
    # use `tkl_*` functions directly from here ...
    
    0 讨论(0)
提交回复
热议问题