2017-10-19 114 views
1

我想访问某种Python中的导入依赖项跟踪,如果有的话。如何获取python模块导入的模块列表

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

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

ModuleFinder(由How to list imports within a Python module?建议)将不起作用,因为应该对已经装载的模块进行检查。

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

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

if __name__ == '__main__': 
    import foo 

那么结果是:

>>> mf = ModuleFinder 
>>> mf.run_script('script.py') 
>>> 'foo' in mf.modules 
True 

如果脚本导入为一个模块,它应该是假的。

我不想列出所有导入的模块 - 只有我的模块导入的模块 - 所以sys.modules(建议What is the best way of listing all imported modules in python?)会返回太多。

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

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

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

from foo import bar 
import baz 

那么结果应该是这样的:

>>> import example 
>>> moduleImports(example) 
{'foo': <module 'foo' from ... >, 
'baz': <module 'baz' from ...>} 

(它可能包含也模块中引入递归或foo.bar给出的酒吧是一个模块)。 (根据How to list imported modules?)的globls()

使用需要我手动处理非模块导入,如:

from foo import bar 
import bar 

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

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

+0

目前尚不清楚为什么你认为'ModuleFinder'不起作用。事实上,它肯定是唯一能*可能工作的东西。您还将如何区分已经加载的模块和由模块首先导入的模块?以及如何识别不在模块全局范围内的导入(例如内部函数)? – ekhumoro

+0

@ekhumoro我不知道为什么SO没有通知我您的评论。看到编辑的问题,然后请让我知道,所以我可以删除[编辑]标签。 – abukaj

+0

您声称'ModuleFinder'不能用于模块显然是错误的 - 请参见[python文档中的示例](https://docs.python.org/2/library/modulefinder.html#example-usage-of- modulefinder)。我没有看到你不应该使用它的任何其他很好的理由。 – ekhumoro

回答

0

可以使用inspect moudule

例如:

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

这里有一个live example

如果你想刚才导入的本地模块使用:

filter(lambda x: inspect.ismodule(x[1]), locals().items()) # filter dependant modules 

另一个live example

+0

谢谢。不幸的是,它有与我目前的解决方案相同的缺点(过滤'globals()')。它忽略了非模块导入(如果从foo导入栏中''foo'不被注意到)。 – abukaj

+0

@abukaj,我不认为你会得到,除非手动指定,因为实际上foo没有被使用,因为python没有把它带到范围:/ – Netwave

+0

我希望有Python模块中的某种导入跟踪。 – abukaj