Есть ли способ получить доступ к родительским модулям в Python - PullRequest
6 голосов
/ 13 марта 2011

Мне нужно знать, есть ли способ доступа к родительским модулям из подмодулей.Если я импортирую субмодуль:

from subprocess import types

У меня есть types - есть ли какая-то магия Python, чтобы получить доступ к модулю subprocess из types?Нечто подобное для классов ().__class__.__bases__[0].__subclasses__().

Ответы [ 4 ]

6 голосов
/ 13 марта 2011

Если вы получили доступ к модулю, вы можете получить его из словаря sys.modules. Python не хранит «родительские указатели» с именами, особенно потому, что отношения не однозначные. Например, используя ваш пример:

>>> 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'>

Если вы заметите наличие types в модуле subprocess, это просто артефакт оператора import types в нем. Вы просто import types, если вам нужен этот модуль.

Фактически, будущая версия subprocess может больше не импортировать types, и ваш код сломается. Вы должны импортировать только имена, которые появляются в списке __all__ модуля; рассмотреть другие имена как детали реализации.

Так, например:

>>> 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']

Вы можете видеть, что большинство имен, видимых в subprocess, являются просто другими модулями верхнего уровня, которые он импортирует.

4 голосов
/ 26 августа 2017

Для потомков я тоже столкнулся с этим и придумал один вкладыш:

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

Часть or '__main__' на тот случай, если вы загрузите файл напрямую, он вернется сам.

0 голосов
/ 13 июля 2018
full_module_name = module.__name__
parent, _, sub = full_module_name.rpartition('.')
if parent:
    parent = import(parent, fromlist='dummy')
0 голосов
/ 13 марта 2011

Я предполагаю, что вы уже не находитесь внутри модуля подпроцесса, вы можете сделать

import somemodule
children = dir(somemodule)

Затем вы можете проверить дочерние элементы подпроцесса с модулем проверки: http://docs.python.org/library/inspect.html

Может быть,Вам пригодится метод getmodule?http://docs.python.org/library/inspect.html#inspect.getmodule

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

На моей машине __package__ возвращает пустое значение для «типов», но может быть более полезным для моих собственных модулей, так как возвращает родительский модуль в виде строки

...