有没有办法访问导入模块对象的父模块?

13 投票
5 回答
18921 浏览
提问于 2025-04-16 13:35

我想知道有没有办法从子模块访问父模块。如果我导入了子模块:

from subprocess import types

我有一个叫 types 的模块,是否有什么Python的技巧可以让我从 types 模块访问 subprocess 模块?类似于这个类的方式 ().__class__.__bases__[0].__subclasses__()

5 个回答

0

在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这些问题可能是因为我们没有正确理解某些概念或者没有按照正确的方式去实现它们。

比如说,变量就像是一个储物箱,我们可以把不同的东西放进去,随时拿出来使用。但是如果我们把东西放错了地方,或者没有正确地命名这个箱子,后面就会很麻烦。

另外,函数就像是一个小工具,可以帮助我们完成特定的任务。我们只需要告诉它要做什么,它就会按照我们的指示去工作。如果我们没有正确地使用这些工具,或者没有给它们提供正确的信息,它们就无法正常工作。

所以,理解这些基本概念是非常重要的,这样才能更好地解决问题,写出更好的代码。

full_module_name = module.__name__
parent, _, sub = full_module_name.rpartition('.')
if parent:
    parent = import(parent, fromlist='dummy')
5

为了将来参考,我也遇到过这个问题,最后想出了这样一句简单的代码:

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

这里的 or '__main__' 这一部分是为了防止你直接加载这个文件时,它会返回自己。

7

如果你访问了一个模块,通常可以通过 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'>

你会发现 subprocess 模块里有 types,这只是因为它里面有一句 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 中大部分可见的名字其实就是它导入的其他顶级模块。

撰写回答