Pregunta

Si bien es bastante trivial en Python para importar un módulo de "niño" en otro módulo y la lista de sus atributos, se hace un poco más difícil cuando se quiere importar todos Módulos de niños.

Estoy construyendo una biblioteca de herramientas para una aplicación 3D existente. Cada herramienta tiene sus propios elementos de menú y submenús. Me gustaría que la herramienta sea responsable de crear sus propios menús ya que muchos de ellos cambiar en función del contexto y de las plantillas. Me gustaría que mi módulo base que sea capaz de encontrar todos los módulos del niño y comprobar si hay una función create_menu() y llamarlo si lo encuentra.

¿Cuál es la manera más fácil de descubrir todos los módulos niño?

¿Fue útil?

Solución

Otros consejos

Creo que la mejor manera de hacer este tipo de cosas plugin está usando entry_points y la API rel="nofollow"> .

Cuando yo era una especie de programación y acaba de empezar 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]

No es seguro o "correcta", pero tal vez vamos a ser útil, sin embargo. Es muy código antiguo por lo que no me pegaba.

La solución anterior que atraviesa el sistema de archivos para encontrar submódulos está bien, siempre y cuando se implementa todos los plugins como un módulo basado en el sistema de archivos.

Una forma más flexible sería una lista de plugins explícita en su módulo principal, y tienen todos los plugins (si un módulo creado por archivo, de forma dinámica, o incluso instancia de una clase) sumándose a la lista de forma explícita. Tal vez a través de una función registerPlugin.

Recuerde:. "Explícito es mejor que implícito" es parte del Zen de Python

Puede intentar globbing el directorio:

import os
import glob

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

A continuación, 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)
scroll top