2011-06-25 103 views
5

我需要的方式在運行時發現,我的每個Python包的子模塊的依賴關係,所以我可以在一個正確的順序初始化它們(見我的電流[編輯:]解決方案here ,這樣做不好),所以起初我使用了標準Python模塊modulefinder,但這太慢了(每個模塊約1-2秒)。Python的依賴關係分析庫

我的下一個選擇是分析每個模塊的所有全局變量,並從全局變量中查找每個子模塊依賴哪個子模塊。 (這是我目前的解決方案編輯:我現在有一個更好的解決方案 - 請參閱我的答案)。這個算法是很多快於模塊搜索器(它需要<每個模塊200ms),但它只適用於相對導入,而不是完全合格的導入樣式,這是不可接受的。

所以,我需要的是兩種:

  • 一個更快的替代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() 

(以防萬一它可以幫到你。)

謝謝!

編輯:我現在有一個解決方案 - 請參閱我的答案。

+0

爲什麼在運行時必須發生這種情況?這些依賴關係在運行時是否會發生變化? –

+0

通常情況下(有一些例外),但我不想爲每個模塊添加額外的依賴關係映射文件(這聽起來像您所建議的),所以我決定在運行時分析每個模塊的依賴關係,時間。 – DangerOnTheRanger

+0

或者你可以用一些懶惰的初始化來實現你的包,以便它們的初始化順序無關緊要。 – rafalotufo

回答

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自己的模塊中,是最不依賴模塊被放置在初始化隊列第一個,也是最依賴的模塊被放置在初始化隊列最後。