Dynamisches Laden von Python-Modulen
Frage
Ich versuche, dynamisch Module laden die ich angelegt habe.
Im Moment funktioniert das richtig:
import structures.index
Aber wenn ich das Gleiche versuchen, indem sie dynamisch zu importieren, schlägt es.
struct = __import__("structures.index")
Fehler geliefert werden:
Error ('No module named structures.index',)
Irgendwelche Ideen, warum?
Edit: Bei der Verwendung von in vollen Umfang (es ist eine Art von Arbeiten?):
struct = __import__("neoform.structures.index")
Dies wirft keinen Fehler, es jedoch nicht, den Index-Modul wird geladen, es stattdessen den „neoform“ Moduls geladen werden.
Das Ergebnis der "Struktur" ist:
<module 'neoform' from '/neoform/__init__.py'>
Auch als Neben Frage, wie kann ich dann eine Klasse innerhalb eines dynamisch geladenen Modul instanziiert? (Vorausgesetzt, alle Module einen gemeinsamen Klassennamen enthalten).
Edit: Lösung: (Dank coonj & Rick) Dieser endete als was funktionierte. Nicht sicher, warum (noch) nicht, aber die fromlist
hatte etwas sein, „offenbar etwas, da es funktionierte, als ich den Brief setzen‚a‘als Wert (seltsam, da die Datei hatte nur 1 Klasse drin).
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))
Lösung
Ich bin mir nicht sicher, was bedeutet „es scheitert“, also wird ich nur erwähnen, dass __import__('structures.index')
sollte in der Tat, Arbeit, aber es hat die Modulnamen im aktuellen Bereich nicht zugeordnet werden. Um das zu tun (und dann eine Klasse in dem dynamisch importierten Modul verwenden), Sie müssen verwenden:
structures = __import__('structures.index')
structures.index.SomeClass(...)
Die vollständigen Einzelheiten über __import__
sind verfügbar hier .
Edit: (basierend auf Frage bearbeiten)
neoform.structures.index
zu importieren, und das index
Modul zurückzukehren, würden Sie wie folgt vor:
structures = __import__('neoform.structures.index',
fromlist=['does not in fact matter what goes here!'])
Wenn Sie also eine Liste von Paketnamen packages
haben, können Sie ihre index
Module importieren und einige MyClass
Klasse für jede mit dem folgenden Code instanziiert:
modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a'])
for pkg in packages ]
objects = [ m.MyClass() for m in modules ]
Andere Tipps
Untermodule zu importieren, müssen Sie sie in der fromlist
arg von __import__()
Fo Beispiel geben, das Äquivalent von:
import structures.index
ist:
structures = __import__('structures', fromlist=['index'])
Um dies zu tun in einer Karte ist ein wenig komplizierter ...
import mod1.index
import mod2.index
import mod3.index
Für die Einfuhr, würden Sie wollen eine neue Funktion zu definieren, die index
Untermodul von jedem Modul zu bekommen:
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
Nun, Sie können dies tun, um Verweise auf alle Indices-Module zu erhalten:
index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])
Auch wenn Sie Submodule greifen wollen, die nicht ‚Index‘ genannt werden, dann können Sie dies tun:
mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y),
['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])
Verwenden Sie in vollem Umfang ( "neoform.structures.index") mit dieser Hilfsmethode.
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-Programmierer hier, aber ich glaube, Sie brauchen die imp Modul
>>> 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!
Warum in aller Welt würden Sie ersetzen
import structures.index
mit
map(__import__, ["structures.index"])
Der erste (a) arbeitet, (b) ist dynamische und (c) direkt unterstützt wird. Welche möglicher Anwendungsfall ist es für den Ersatz leicht zu ändern, Klartextquelle mit etwas komplexen?
Kurz gesagt: dies nicht tun. Es macht keinen Wert hat.
Bearbeiten
Die „Ich erhalte den Import aus einer Datenbank“ ist eine edle Anstrengung, aber noch nicht sinnvoll. Welche Codeblock ist abhängig von diesen Einfuhren? Das ganze Codeblock - Importe und alle - ist das, was Sie ausführen möchten. Die ganzen Codeblock - Importe, Erklärungen und alles -. Sollte eine einfache alte Python-Modul-Datei
Importieren Sie diesen Codeblock aus dem Dateisystem. Verwenden Sie die Datenbank zu identifizieren, welche Datei, den Autor der Datei - alles, was Sie für die Datenbank verwenden möchten. Aber einfach importieren und das Modul eine möglichst einfache Art und Weise auszuführen.
Wirklich spät Beitrag hier. Aber ich war auf Google für diese Frage zu suchen. Ich habe einigen Versuch und Irrtum. Nicht sicher, ob diese Schnipsel helfen aber hier ist es. Verwenden sie für Flask Ort.
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)