我需要一种在运行时查找每个Python包的子模块的依赖关系的方法,这样我就可以按正确的顺序初始化它们(参见我当前的[编辑: 前< / em>]解决方案here,但效果不好),所以起初我使用标准的Python模块 modulefinder ,但这太慢了(约1-2秒)每个模块)。
我的下一个选择是分析每个模块的所有全局变量,并从每个子模块所依赖的子模块的全局变量中找到。 (这是我目前的解决方案编辑:我现在有更好的解决方案 - 请参阅我的回答)。此算法 比 modulefinder 更快(每个模块需要<200ms),但它仅适用于相对导入,而不是完全限定的导入样式,即不可接受的。
所以,我需要的是:
注意:我在每个模块的开头调用我的依赖分析器,如下所示:
# 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()
(万一它可以帮助你。)
谢谢!
编辑:我现在有一个解决方案 - 请参阅我的回答。
答案 0 :(得分:2)
我想我有一个解决我自己问题的方法:)
以下是上面讨论的 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 的调用。但是,由于所有import语句都放在之前在您自己的模块中调用 gendeps ,因此最少依赖的模块首先放在初始化队列中,并且最多相关模块最后放在初始化队列中。