2009-05-26 13 views
12

Si bien es bastante trivial en Python importar un módulo "secundario" en otro módulo y enumerar sus atributos, se vuelve un poco más difícil cuando desea importar todos los módulos secundarios.¿Cómo encontrar todos los módulos secundarios en Python?

Estoy creando una biblioteca de herramientas para una aplicación 3D existente. Cada herramienta tiene su propio elemento de menú y submenús. Me gustaría que la herramienta sea responsable de crear sus propios menús, ya que muchos de ellos cambian según el contexto y las plantillas. Me gustaría que mi módulo base pueda encontrar todos los módulos secundarios y buscar una función create_menu() y llamarla si la encuentra.

¿Cuál es la forma más fácil de descubrir todos los módulos secundarios?

+0

¿Esto está relacionado? [('pkg_resources' del paquete setuptools)] (http://jeetworks.org/node/49) –

+1

Utilice [pkgutil.walk_packages] (http://docs.python.org/library/pkgutil.html#pkgutil. walk_packages). Los módulos – Dag

+1

no son paquetes –

Respuesta

0

usando dir() y imp module

+0

¡imp parece el módulo exacto que necesito! Gracias. – Soviut

+11

Esa es una respuesta bastante escueta, no veo por qué fue aceptada. La documentación para dir() asume que su objeto ya tiene atributos. ¿Podría elaborar y decir * cómo * uno debería usar dir() para encontrar módulos que aún no se importaron? – bignose

+3

Nop: '$ mkdir foo $ toque foo/__ init__.py $ touch foo/bar.py $ pitón Python 2.7.1+ (r271: 86832, abr 11 2011, la 18:05:24) [GCC 4.5.2] en linux2 Escriba "ayuda", "derechos de autor", "créditos" o "licencia" para obtener más información.foo >>> import >>> foo >>> dir (foo) [ '__builtins__', '__doc__', '__file__', '__name__ ',' __package__ ',' __path__ '] >>> de la barra de importación foo >>> barra ' –

1

Cuando era una especie y programación empezando en Python que he escrito esto para mi bot de IRC modular:


    # Load plugins 

    _plugins = [] 

    def ifName(name): 
     try: 
      return re.match('([^_.].+)\.[^.]+', a).group(1) 
     except: 
      return None 

    def isValidPlugin(obj): 
     from common.base import PluginBase 
     try: 
      if obj.__base__ == PluginBase: 
       return True 
      else: 
       return False 
     except: 
      return False 

    plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))])) 
    for plugin_name in plugin_names: 
     try: 
      plugin = __import__('plugins.'+plugin_name, fromlist=['plugins']) 
      valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)]) 
      _plugins.extend(valid_plugins) 
     except Exception, e: 
      logger.exception('Error loading plugin %s', plugin_name) 

    # Run plugins 

    _plugins = [klass() for klass in _plugins] 

que no es seguro o "correcta", pero tal vez seamos útiles sin embargo. Es muy código antiguo, así que por favor no me ganes.

+0

Sí, debe usar el módulo imp como se mencionó en dfa. – deno

-1

Usted puede intentar glob Bing el directorio:

import os 
import glob 

modules = glob.glob(os.path.join('/some/path/to/modules', '*.py')) 

entonces puede intentar importarlos:

checked_modules 
for module in modules: 
    try: 
     __import__(module, globals(), locals()) # returns module object 
    except ImportError: 
     pass 
    else: 
     checked_modules.append(module) 
3

Creo que la mejor manera de hacer este tipo de cosas plugin está utilizando entry_points y la API for querying them.

+0

Esta debería ser la respuesta aceptada. El registro de módulos a través de puntos de entrada es un enfoque mucho más claro, deliberado y pitónico cuando desea descubrirlos en tiempo de ejecución, y no tiene el efecto secundario de hacer que todos ellos se importen de la forma en que 'pkgutil.walk_packages' lo hace . –

1

La solución anterior que atraviesa el sistema de archivos para encontrar submódulos está bien siempre que implemente cada complemento como un módulo basado en el sistema de archivos.

Una manera más flexible sería una lista explícita de complementos en su módulo principal, y tener cada complemento (ya sea un módulo creado por archivo, dinámicamente o incluso instancia de una clase) agregándose a esa lista explícitamente. Tal vez a través de una función registerPlugin.

Recuerde: "explícito es mejor que implícito" es parte del zen de python.

+0

para que esto funcione, debe asegurarse de que los módulos de complementos se importen al iniciar su aplicación, de lo contrario no tendrán la posibilidad de registrarse. es un problema de huevo y pollo sin atravesar/importar automáticamente módulos, terminas importando manualmente todos los módulos en tu módulo principal, anulando la necesidad de una función de registro pero rompiendo el principio de que el principal no necesita saber sobre complementos específicos – Anentropic

Cuestiones relacionadas