2

如何从 python 脚本中获取(查找位置)动态导入的模块?

因此,据我了解,python 可以动态(在运行时)加载模块。无论是使用_ import _(module_name),还是使用exec "from x import y",或者使用imp.find_module("module_name")然后imp.load_module(param1, param2, param3, param4)

知道我想获取 python 文件的所有依赖项。这将包括获取(或至少我尝试过)动态加载的模块,这些模块通过使用硬编码的字符串对象或由函数/方法返回的模块加载。

对于正常的import module_namefrom x import y,您可以手动扫描代码或使用 module_finder。

因此,如果我想复制一个 python 脚本及其所有依赖项(包括自定义动态加载的模块),我应该怎么做?

4

5 回答 5

3

你不能;编程的本质(在任何语言中)意味着您无法在不实际执行的情况下预测将执行的代码。因此,您无法确定可以包含哪些模块。

用户输入进一步混淆了这一点,请考虑:__import__(sys.argv[1]).

关于第一个问题有很多理论信息,通常被描述为停机问题,第二个显然做不到。

于 2011-09-16T08:08:32.197 回答
2

从理论的角度来看,您永远无法确切知道正在导入什么/在哪里导入模块。从实际的角度来看,如果您只是想知道模块在哪里,请检查module.__file__属性或在加载模块时运行脚本python -v以查找文件。这不会为您提供所有可能被加载的模块,但会获得大多数具有大部分正常代码的模块。

另请参阅:如何找到 Python 模块源的位置?

于 2011-09-16T08:22:48.443 回答
1

只是一个想法,我不确定它是否会起作用:

您可以编写一个包含__builtin__.__import__. 这个包装器将保存对旧的引用__import__,然后分配一个函数来__builtin__.__import__执行以下操作:

  1. 每当调用时,获取当前堆栈跟踪并计算调用函数。也许globals参数 to中的信息__import__就足够了。
  2. 获取该调用函数的模块并存储该模块的名称以及将导入的内容
  3. 将呼叫重定向到真实的__import__

完成此操作后,您可以使用 调用您的应用程序python -m magic_module yourapp.py。魔术模块必须将信息存储在您以后可以检索到的地方。

于 2011-09-16T08:44:14.410 回答
1

这不可能做到 100% 准确。我在这里回答了一个类似的问题:Dependency Testing with Python

于 2011-09-16T08:07:27.393 回答
0

这真是个问题。

静态分析是关于预测所有可能的运行时执行路径并确保程序完全停止特定输入。

这相当于停止问题,不幸的是没有通用的解决方案。

解决动态依赖关系的唯一方法是运行代码。

于 2011-09-16T08:27:03.717 回答