Python 依赖分析库
我需要一种方法,在运行时找到我每个Python包的子模块之间的依赖关系,这样我才能按正确的顺序初始化它们(可以看看我之前的解决方案这里,不过效果不太好)。最开始我用了Python的标准模块modulefinder,但是速度太慢了(每个模块大约需要1-2秒)。
接下来,我尝试分析每个模块的全局变量,看看这些全局变量中每个子模块依赖于哪个子模块。(这是我现在的解决方案编辑:我现在有了更好的解决方案 - 请看我的回答)。这个算法比modulefinder快多了(每个模块少于200毫秒),但它只适用于相对导入,而不支持完全限定的导入方式,这让我觉得不太能接受。
所以,我需要的是:
- 一个比modulefinder更快的替代方案
- 一个替代的算法
注意:我在每个模块开始时调用我的依赖分析器,像这样:
# File my_package/module3.py
import my_package.module1 # Some misc. module
import my_package.module2 # Some other misc. module
import my_package.dependency_analyzer
my_package.dependency_analyzer.gendeps()
(希望这对你有帮助。)
谢谢!
编辑:我现在有了解决方案 - 请看我的回答。
1 个回答
3
我觉得我找到了自己问题的解决办法 :)
下面是关于上面提到的dependency_analyzer模块应该包含的内容:
import sys
from sys import _getframe as getframe
import atexit
examined_modules = []
def gendeps():
"""Adds the calling module to the initialization queue."""
# Get the calling module's name, and add it to the intialization queue
calling_module_name = getframe(1).f_globals['__name__']
examined_modules.append(calling_module_name)
def init():
"""Initializes all examined modules in the correct order."""
for module in examined_modules:
module = sys.modules[module]
if hasattr(module, 'init'):
module.init()
if hasattr(module, 'deinit'):
# So modules get de-initialized in the correct order,
# as well
atexit.register(module.deinit)
在每个模块的开始部分(在所有导入语句之后 - 这一点很重要),会调用gendeps。这个算法之所以有效,是因为每次导入一个模块时,都会执行对gendeps的调用。不过,由于你自己的模块中所有的导入语句都放在了调用gendeps之前,所以依赖关系最少的模块会最先放入初始化队列,而依赖关系最多的模块则会最后放入初始化队列。