Question

Il est assez trivial en Python pour importer un module « enfant » dans un autre module et la liste de ses attributs, il devient un peu plus difficile quand vous voulez importer tous modules enfant.

Je construis une bibliothèque d'outils pour une application 3D existante. Chaque outil a ses propres menus de l'élément de menu et sous. Je voudrais que l'outil soit chargé de créer ses propres menus que beaucoup d'entre eux changent en fonction du contexte et des modèles. Je voudrais que mon module de base pour être en mesure de trouver tous les modules enfant et vérifier une fonction create_menu() et l'appeler si elle le trouve.

Quelle est la meilleure façon de découvrir tous les modules enfant?

Était-ce utile?

La solution

Autres conseils

Je pense que la meilleure façon de faire ce genre de chose plugin utilise entry_points et l'API pour les interroger .

Quand j'étais genre et la programmation en Python juste de commencer, je l'ai écrit pour mon robot modulaire IRC:


    # 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]

Il est pas sécurisé ou « bonne » façon, mais peut-être que nous allons être utile quand même. Il est très ancien code si s'il vous plaît ne me battez pas.

La solution ci-dessus traversant le système de fichiers pour trouver des sous-modules est ok aussi longtemps que vous mettre en œuvre tous les plug-in en tant que module à base de système de fichiers.

Une façon plus souple serait une liste de plug-in explicite dans votre module principal, et ont tous les plug-in (si un module créé par fichier, dynamiquement, ou même instance d'une classe) s'ajoutant à cette liste explicitement. Peut-être via une fonction registerPlugin.

Rappelez-vous:. « Explicite est mieux que implicite » fait partie du zen de python

Vous pouvez globbing le répertoire:

import os
import glob

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

Ensuite, vous pouvez essayer de les importer:

checked_modules
for module in modules:
    try:
        __import__(module, globals(), locals()) # returns module object
    except ImportError:
        pass
    else:
        checked_modules.append(module)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top