如何获取python模块导入的模块列表

abu*_*kaj 5 python python-module python-import python-2.7 python-3.x

如果有的话,我想在 Python 中访问某种导入依赖项跟踪。

我决定在我的模块中添加一个__dependencies__描述模块导入的所有模块版本的字典。

我想要一种自动获取模块导入的模块列表的方法。最好在模块的最后一行。

ModuleFinder(如如何在 Python 模块中列出导入所建议的那样)将不起作用,因为应对已加载的模块执行检查。

另一个问题ModuleFinder是它检查 Python脚本(带if __name__ == '__main__'分支),而不是模块。

如果我们考虑一个玩具脚本 script.py:

if __name__ == '__main__':
    import foo
Run Code Online (Sandbox Code Playgroud)

那么结果是:

>>> mf = ModuleFinder
>>> mf.run_script('script.py')
>>> 'foo' in mf.modules
True
Run Code Online (Sandbox Code Playgroud)

如果脚本作为模块导入,则应该为 False。

我不想列出所有导入的模块 - 仅由我的模块导入的模块 - 所以sys.modules(建议在 python 中列出所有导入的模块的最佳方法是什么?)会返回太多。

我可以比较sys.modules模块代码开头和结尾的快照。但是那样我会错过我的模块使用的所有模块,但之前由任何其他模块导入。

列出模块从中导入对象的模块也很重要。

如果我们考虑一个玩具模块 example.py:

from foo import bar
import baz
Run Code Online (Sandbox Code Playgroud)

那么结果应该是这样的:

>>> import example
>>> moduleImports(example)
{'foo': <module 'foo' from ... >,
 'baz': <module 'baz' from ...>}
Run Code Online (Sandbox Code Playgroud)

(它也可能包含递归导入的模块或foo.bar给定的 bar 是一个模块)。

使用globls()(根据如何列出导入的模块?)需要我手动处理非模块导入,例如:

from foo import bar
import bar
Run Code Online (Sandbox Code Playgroud)

我怎样才能避免这种情况?

到目前为止,我的解决方案还有另一个问题。PyCharm 倾向于在重构时清理我的手动导入,这使得它很难保持工作。

Net*_*ave 6

您可以使用检查模块

例如:

import inspect
import os
m = inspect.getmembers(os) # get module content
filter(lambda x: inspect.ismodule(x[1]), m) # filter dependant modules
Run Code Online (Sandbox Code Playgroud)

这里有一个活生生的例子

如果您想导入本地模块,只需使用:

filter(lambda x: inspect.ismodule(x[1]), locals().items()) # filter dependant modules
Run Code Online (Sandbox Code Playgroud)

另一个活生生的例子