Is there a way to access parent modules in Python

2019-01-28 00:25发布

I need to know if there is a way to access parent modules from submodules. If I import submodule:

from subprocess import types

I have types - is there some Python magic to get access to subprocess module from types? Something similar to this for classes ().__class__.__bases__[0].__subclasses__().

4条回答
何必那么认真
2楼-- · 2019-01-28 00:52

I assume you are not inside the subprocess module already, you could do

import somemodule
children = dir(somemodule)

Then you could inspect the children of subprocess with the inspect module: http://docs.python.org/library/inspect.html

Maybe the getmodule method would be useful for you? http://docs.python.org/library/inspect.html#inspect.getmodule

import inspect
parent_module = inspect.getmodule(somefunction)
children = dir(parent_module)
package = parent_module.__package__

On my machine __package__ returns empty for 'types', but can be more useful for my own modules as it does return the parent module as a string

查看更多
我命由我不由天
3楼-- · 2019-01-28 00:54

If you've accessed a module you can typically get to it from the sys.modules dictionary. Python doesn't keep "parent pointers" with names, particularly because the relationship is not one-to-one. For example, using your example:

>>> from subprocess import types
>>> types
<module 'types' from '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/types.pyc'>
>>> import sys
>>> sys.modules['subprocess']
<module 'subprocess' from '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.pyc'>

If you'll note the presence of types in the subprocess module is just an artifact of the import types statement in it. You just import types if you need that module.

In fact, a future version of subprocess may not import types any more, and your code will break. You should only import the names that appear in the __all__ list of a module; consider other names as implementation details.

So, for example:

>>> import subprocess
>>> dir(subprocess)
['CalledProcessError', 'MAXFD', 'PIPE', 'Popen', 'STDOUT', '_PIPE_BUF', '__all__', '__builtins__', '__doc__',
 '__file__', '__name__', '__package__', '_active', '_cleanup', '_demo_posix', '_demo_windows', '_eintr_retry_call',
 '_has_poll', 'call', 'check_call', 'check_output', 'errno', 'fcntl', 'gc', 'list2cmdline', 'mswindows', 'os',
 'pickle', 'select', 'signal', 'sys', 'traceback', 'types']
>>> subprocess.__all__
['Popen', 'PIPE', 'STDOUT', 'call', 'check_call', 'check_output', 'CalledProcessError']

You can see that most of the names visible in subprocess are just other top-level modules that it imports.

查看更多
劫难
4楼-- · 2019-01-28 00:54

For posterity, I ran into this also and came up with the one liner:

import sys
parent_module = sys.modules['.'.join(__name__.split('.')[:-1]) or '__main__']

The or '__main__' part is just in case you load the file directly it will return itself.

查看更多
爱情/是我丢掉的垃圾
5楼-- · 2019-01-28 00:56
full_module_name = module.__name__
parent, _, sub = full_module_name.rpartition('.')
if parent:
    parent = import(parent, fromlist='dummy')
查看更多
登录 后发表回答