Bonne façon dynamique d'importer un module avec une relative des importations?

J'ai besoin dynamiquement des modules d'importation dans mon projet d'un autre paquet.

La structure est comme:

project_folder/
    project/
        __init__.py
        __main__.py
    plugins/
        __init__.py
        plugin1/
            __init__.py
            ...
        plugin2/
            __init__.py
            ...

J'ai fait cette fonction pour charger un module:

import os

from importlib.util import spec_from_file_location, module_from_spec


def load_module(path, name=""):
    """ loads a module by path """
    try:
        name = name if name != "" else path.split(os.sep)[-1]  # take the module name by default
        spec = spec_from_file_location(name, os.path.join(path, "__init__.py"))
        plugin_module = module_from_spec(spec)
        spec.loader.exec_module(plugin_module)
        return plugin_module
    except Exception as e:
        print("failed to load module", path, "-->", e)

Il fonctionne, à moins que le module utilise relative des importations:

failed to load module /chemin/vers/plugins/plugin1 --> Parent module "plugin1' a pas été chargé, ne peut pas effectuer relative à l'importation

Ce que je fais mal?

  • La solution est donnée dans le cette réponse: vous devez également ajouter le module importé à sys.modules de sorte que la relative à l'importation des œuvres. I. e. inclure sys.modules[spec.name] = plugin_module juste avant l'appel à spec.loader.exec_module(plugin_module).
InformationsquelleAutor user3638162 | 2016-06-14