如何从python脚本中获取(找到(动态导入的模块?
因此,根据我的理解,python可以动态地(在运行时(加载模块。无论是使用_import_(module_name(,还是使用exec"from x import y">、使用1imp.find_module("module_name"(imp.load_module(param1、param2、param3、param4(。
知道我想获得python文件的所有依赖项。这将包括获取(或者至少我尝试过(动态加载的模块,这些模块是通过使用硬编码字符串对象加载的,或者是通过函数/方法返回的。
对于正常的从x导入module_name和,您可以手动扫描代码或使用module_finder。
所以,如果我想复制一个python脚本及其所有依赖项(包括自定义动态加载的模块(,我应该怎么做?
你不能;编程(在任何语言中(的本质意味着,如果不实际执行,你就无法预测将执行什么代码。因此,你无法判断哪些模块可以被包括在内。
用户输入进一步混淆了这一点,请考虑:__import__(sys.argv[1])
。
关于第一个问题,有很多理论信息,通常被描述为Halting问题,第二个问题显然是做不到的。
从理论角度来看,您永远不可能确切地知道要导入的模块是什么/在哪里。从实际角度来看,如果您只是想知道模块在哪里,请检查module.__file__
属性或在python -v
下运行脚本,以便在加载模块时查找文件。这不会为您提供所有可能加载的模块,但会为大多数模块提供大部分正常代码。
另请参阅:如何查找Python模块源代码的位置?
这不可能做到100%准确。我在这里回答了一个类似的问题:使用Python 进行依赖性测试
这只是一个想法,我不确定它是否有效:
您可以编写一个包含__builtin__.__import__
包装器的模块。这个包装器将保存对旧__import__
的引用,然后为__builtin__.__import__
分配一个执行以下操作的函数:
- 无论何时调用,都要获取当前stacktrace并计算出调用函数。也许
globals
参数到__import__
中的信息就足够了 - 获取该调用函数的模块,并存储该模块的名称以及将导入的内容
- 将呼叫重定向到真正的
__import__
完成此操作后,您可以使用python -m magic_module yourapp.py
调用您的应用程序。魔术模块必须将信息存储在以后可以检索的地方。
这是个很大的问题。
静态分析是关于预测所有可能的运行时执行路径,并确保程序因特定输入而停止。
这相当于暂停问题,不幸的是没有通用的解决方案。
解决动态依赖关系的唯一方法是运行代码