【问题标题】:How to get a list of modules imported by a python module如何获取由python模块导入的模块列表
【发布时间】:2018-03-31 20:51:12
【问题描述】:

如果有的话,我想在 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

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

我不想列出所有导入的模块——只列出我的模块导入的模块——所以sys.modulesWhat 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 给定的 bar 是一个模块)。

使用globls()(根据How to list imported modules?)需要我手动处理非模块导入,例如:

from foo import bar
import bar

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

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

【问题讨论】:

  • 不清楚为什么您认为ModuleFinder 不起作用。事实上,它肯定是唯一可能可能起作用的东西。您还要如何区分已经加载的模块和模块首先导入的模块?您如何识别不在模块全局范围内的导入(例如内部函数)?
  • @ekhumoro 我不知道为什么 SO 没有通知我您的评论。请查看已编辑的问题,然后请告诉我,以便我删除 Edit 标签。
  • 您声称 ModuleFinder 不适用于模块显然是错误的 - 请参阅 example in the python docs。我看不出你不应该使用它的任何其他充分理由。
  • 你能举个更好的例子吗?
  • @ekhumoro 请指出导入模块的示例,然后将导入的模块(不是str)传递给ModuleFinder。我看不到。另外,请参阅更新后的问题 - 我在“main”分支添加了一个 ModuleFinder 失败示例。

标签: python python-2.7 python-3.x python-import python-module


【解决方案1】:

您可以使用inspect 模块

例如:

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

【讨论】:

  • 谢谢。不幸的是,它与我当前的解决方案具有相同的缺点(过滤globals())。它省略了非模块导入(如果from foo import bar foo 未被注意到)。
  • @abukaj,除非手动指定,否则我认为您不会得到它,因为实际上 foo 没有被使用,因为 python 没有将它带入范围:/
  • 我希望 Python 模块中有某种导入跟踪。
  • 现场示例已损坏。
  • 您可以将谓词传递给getmembers,即inspect.getmembers(os, inspect.ismodule)
猜你喜欢
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 2013-12-13
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多