Есть ли способ получить доступ к родительским модулям в Python

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

from subprocess import types

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

5 ответов

Решение

Если вы получили доступ к модулю, вы можете получить к нему из 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 это просто другие модули верхнего уровня, которые он импортирует.

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

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

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

full_module_name = module.__name__
parent, _, sub = full_module_name.rpartition('.')
if parent:
    parent = import(parent, fromlist='dummy')
      Best way worked for us was 

Let' say folder structure 

src
 |demoproject
 |
 |--> uimodule--> ui.py
 |--> backendmodule --> be.py
 setup.py
                 
1. Create installable package out of the project
2. Have __init__.py in all the directory(module)
3. create setup.py [ Keep in top level folder, here inside src]
Sample 

from setuptools import setup, find_packages

    setup(
        name="demopackage",
        version="1",
        packages=find_packages(exclude=["tests.*", "tests"]),
        author='',
        author_email='',
        description="",
        url="",
        )
        
4. From src folder, create installable package
   pip3 install .
5. this will install a package --> demopackage
6. Now from any of your module you can access any module, ex 

7. from ui.py to access be.py function calldb(), make below import

из demopackage.backendmodule.be импортировать calldb

      8. and so on, when you a new folder into your project just add __init__.py in that folder and it will be accessible, just like above, but you have to execute `"pip3 install ."` 

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

import somemodule
children = dir(somemodule)

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

Может быть, метод getmodule был бы полезен для вас? http://docs.python.org/library/inspect.html

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

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

Другие вопросы по тегам