Python依赖分析器库

Dan*_*ger 5 python dependency-management

我需要一种方法在运行时找到我的每个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()
Run Code Online (Sandbox Code Playgroud)

(以防它可以帮助你.)

谢谢!

编辑:我现在有一个解决方案 - 看我的答案.

Dan*_*ger 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)
Run Code Online (Sandbox Code Playgroud)

现在,在每个模块的开始处(在所有 import 语句之后- 这是至关重要的),将调用gendeps。该算法之所以有效,是因为每次导入模块时,都会执行对gendeps 的调用。但是,由于所有 import 语句都放置在您自己的模块中对gendeps的调用之前,因此最不依赖的模块首先放置在初始化队列中,而最依赖的模块最后放置在初始化队列中。