Question

Je suis en train de charger dynamiquement des modules que j'ai créés.

En ce moment, ce fonctionne correctement:

import structures.index

Mais si je tente la même chose en importer dynamiquement, il échoue.

struct = __import__("structures.index")

Erreur fourni est la suivante:

Error ('No module named structures.index',)

Toutes les idées pourquoi?


Edit: Lorsque vous utilisez la portée complète (il sorte de travaux?):

struct = __import__("neoform.structures.index")

Cela ne jette pas des erreurs, cependant, il ne se charge pas le module d'index, il est le chargement du module « neoform » à la place.

Le résultat de "struct" est:

<module 'neoform' from '/neoform/__init__.py'>

En outre, comme une question de côté, comment puis-je instancier puis une classe dans un module chargé dynamiquement? (En supposant que tous les modules contiennent un nom de classe commune).

Edit: Solution: (merci coonj et Rick) Cela a fini par être ce qui a fonctionné. Je ne sais pas pourquoi (encore), mais le fromlist devait être quelque chose « quoi que ce soit en apparence, car il a travaillé quand je mets la lettre « a » comme valeur (étrange, étant donné que le fichier avait seulement 1 classe en elle).

def get_struct_module(self, name):
    try:
        return = __import__("neoform.structures." + name, fromlist='*')
    except ImportError, e:
        self.out.add("Could not load struct: neoform.structure." + name + "\n\n" + "Error " + str(e.args))
Était-ce utile?

La solution

Je ne suis pas sûr de ce que « il ne » signifie, donc je vais juste mentionner que __import__('structures.index') devrait, en fait, le travail, mais il ne lui assigne pas le nom du module dans le périmètre actuel. Pour ce faire (et utiliser une classe dans le module dynamique importé), vous devrez utiliser:

structures = __import__('structures.index')
structures.index.SomeClass(...)

Les détails sur __import__ sont disponibles .

Edit: (basé sur edit question)

Pour importer neoform.structures.index et retourner le module index, vous procédez comme suit:

structures = __import__('neoform.structures.index', 
                        fromlist=['does not in fact matter what goes here!'])

Donc, si vous avez une liste de noms de paquets packages, vous pouvez importer leurs modules index et instancier une classe MyClass pour chacun utilisant le code suivant:

modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a']) 
            for pkg in packages ]
objects = [ m.MyClass() for m in modules ]

Autres conseils

Pour importer des sous-modules, vous devez les spécifier dans le arg fromlist de __import__()
Fo exemple, l'équivalent de:

import structures.index

est:

structures = __import__('structures', fromlist=['index'])

Pour ce faire, dans une carte est un peu plus délicat ...

import mod1.index
import mod2.index
import mod3.index

Pour les importations, vous souhaitez définir une nouvelle fonction pour obtenir le sous-module index de chaque module:

def getIndexMods(mod_names):
  mod_list = map(lambda x: __import__(x, fromlist='index'))
  index_mods = [mod.index for mod in mod_list]
  return index_mods

Maintenant, vous pouvez le faire pour obtenir des références à tous les modules d'index:

index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])

En outre, si vous voulez saisir des sous-modules qui ne sont pas nommés « index », vous pouvez alors faire ceci:

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])

Utiliser la portée complète (le "neoform.structures.index") avec cette méthode d'aide.

def import_module(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

module = import_module("neoform.structures.index")
# do stuff with module

Java programmeur, mais je pense que vous avez besoin diablotin Module

>>> import imp
>>> fm = imp.find_module('index', ['./structures']) # for submodule
>>> mymod = imp.load_module('structures.index', *fm)
>>> mymod
<module 'structures.index' from './structures/index.pyc'>
>>> x = mymod.insideIndex()
Initialising index class...

Voila!

Pourquoi diable voulez-vous remplacer

import structures.index

avec

map(__import__, ["structures.index"])

La première (a) fonctionne, (b) dynamique et (c) est supporté directement. Quel cas possible l'utilisation est là pour remplacer facile à changer, source de texte brut avec quelque chose de plus complexe?

En bref: ne le faites pas. Il n'a pas de valeur.


Modifier

Le « Je reçois l'importation à partir d'une base de données » est un noble effort, mais pas encore sensible. Quel bloc de code dépend de ces importations? Ce bloc entier de code - importations et tout - est ce que vous voulez exécuter. Ce bloc entier de code - importations, déclarations et tout -. Doit être un fichier module python bon vieux

Importer ce bloc de code du système de fichiers. Utilisez la base de données pour identifier le fichier, l'auteur du fichier - tout ce que vous voulez utiliser la base de données. Mais simplement importer et d'exécuter le module le plus simple possible.

vraiment en retard post ici. Mais je cherchais cette question sur Google. Je l'ai fait quelques essais et erreurs. Je ne sais pas si cet extrait va aider, mais ici il est. Son utilisation pour le site Flask.

modules = ['frontend', 'admin']
for module in modules:
    mod = __init__('controllers.%s' % module, fromlist=[module])
    app.register_blueprint(mod.blueprint_mod)


# or
from importlib import import_module
modules = ['frontend', 'admin']
for module in modules:
    mod = import_module('controllers.%s' % module)
    app.regitster_blueprint(mod.blueprint_mod)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top