2011-06-25 17 views
5

necesito una manera de encontrar las dependencias para cada uno de los sub-módulos de mi paquete de Python en tiempo de ejecución para que pueda inicializarlas en un orden adecuado (ver mi actual [EDIT:ex] solución here , que no funciona bien), así que al principio utilicé el módulo de Python , el buscador de módulos, pero era demasiado lento (~ 1-2 segundos por módulo).Python analizador de dependencias de bibliotecas

Mi siguiente opción fue analizar todas las variables globales de cada módulo, y encontrar de esas variables globales de qué submódulo depende cada submódulo. (Esta es mi solución actual EDITAR: Tengo una mejor solución ahora - ver mi respuesta). Este algoritmo es mucho más rápido que módulo buscador (toma < 200ms por módulo), pero solo funciona para las importaciones relativas, en lugar del estilo de importación totalmente calificado, que es inaceptable.

Por lo tanto, lo que necesito es o bien:

  • Una alternativa más rápida a ModuleFinder
  • Un algoritmo alternativo

NOTA: llamar a mi analizador de la dependencia en el inicio de cada módulo, así:

# 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() 

(Sólo en caso de que le ayude alguna.)

¡Gracias!

EDIT: Tengo una solución ahora - ver mi respuesta.

+0

¿Por qué tiene que pasar esto en tiempo de ejecución? ¿Estas dependencias cambian en el tiempo de ejecución? –

+0

Normalmente (hay algunas excepciones), pero no quiero agregar un archivo de mapa de dependencia adicional para cada uno de mis módulos (que suena como lo que está sugiriendo), así que decidí analizar las dependencias de cada módulo en ejecución. hora. – DangerOnTheRanger

+0

O podría implementar sus paquetes con alguna inicialización lenta, de modo que su orden de inicialización no importe. – rafalotufo

Respuesta

2

creo que tengo una solución a mi propia pregunta :)

Esto es lo que iría en el módulo dependency_analyzer hablado de arriba:

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) 

Ahora, al comienzo de cada módulo (después de todas las declaraciones de importación - esto es crucial), se realiza una llamada a gendeps. Este algoritmo funciona porque cada vez que se importa un módulo, se ejecuta esa llamada a gendeps. Sin embargo, dado que todas las instrucciones de importación se ubican antes de la llamada a gendeps en su propio módulo, los módulos menos dependientes se colocan primero en la cola de inicialización, y los módulos más dependientes se colocan en la cola de inicialización último .

Cuestiones relacionadas