Библиотека анализатора зависимостей Python - PullRequest
5 голосов
/ 25 июня 2011

Мне нужен способ найти зависимости для каждого из подмодулей моего пакета Python во время выполнения, чтобы я мог инициализировать их в правильном порядке (см. Мой текущий [ РЕДАКТИРОВАТЬ: прежний ] решение здесь , что не очень хорошо работает, поэтому сначала я использовал стандартный модуль Python modulefinder , но это было слишком медленно (~ 1-2 секунды наmodule).

Моим следующим выбором было проанализировать все глобальные переменные каждого модуля и найти из этих глобальных переменных, от какого подмодуля зависит каждый подмодуль.(Это мое текущее решение РЕДАКТИРОВАТЬ: Теперь у меня есть лучшее решение - см. Мой ответ).Этот алгоритм намного быстрее, чем modulefinder (он требует <200 мс на модуль), но он работает только для относительного импорта, а не для полностью определенного стиля импорта, что недопустимо. </p>

Итак, мне нужно либо:

  • Более быстрая альтернатива 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 Ответ

2 голосов
/ 27 июня 2011

Я думаю, что у меня есть решение моего собственного вопроса:)

Вот что пойдет в модуль 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 в вашем собственном модуле, наименее зависимые модули сначала помещаются в очередь инициализации, а наиболее зависимые модули помещаются в очередь инициализации в последнюю очередь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...