Ich habe eine Schnur, sagen wir : abc.def.ghi.jkl.myfile.mymethod
. Wie importiere ich dynamisch mymethod
?
So habe ich es gemacht:
def get_method_from_file(full_path):
if len(full_path) == 1:
return map(__import__,[full_path[0]])[0]
return getattr(get_method_from_file(full_path[:-1]),full_path[-1])
if __name__=='__main__':
print get_method_from_file('abc.def.ghi.jkl.myfile.mymethod'.split('.'))
Ich frage mich, ob der Import einzelner Module überhaupt erforderlich ist.
Bearbeiten: Ich verwende Python Version 2.6.5.
python
dynamic
import
dynamic-import
Lakshman Prasad
quelle
quelle
importlib.import_module()
over__import__()
: docs.python.org/2/library/functions.html#__import__ - für 2.7+ empfehlen.import_module
+rsplit
= Der einzig wahre Weg.Sie müssen die einzelnen Module nicht importieren. Es reicht aus, das Modul zu importieren, aus dem Sie einen Namen importieren möchten, und das folgende
fromlist
Argument anzugeben:def import_from(module, name): module = __import__(module, fromlist=[name]) return getattr(module, name)
abc.def.ghi.jkl.myfile.mymethod
Rufen Sie für Ihr Beispiel diese Funktion als aufimport_from("abc.def.ghi.jkl.myfile", "mymethod")
(Beachten Sie, dass Funktionen auf Modulebene in Python als Funktionen und nicht als Methoden bezeichnet werden.)
Für eine so einfache Aufgabe bietet die Verwendung des
importlib
Moduls keinen Vorteil .quelle
myClass = getattr(__import__("module.to.import", fromlist=["myClassName"]), "myClassName")
. Danke für die Hilfe!__import__
Ansatz funktioniert. Aber versuche zu rennenhelp(__import__)
. Darin heißt es: "Da diese Funktion für den Python-Interpreter und nicht für den allgemeinen Gebrauch bestimmt ist, ist es besser,importlib.import_module()
ein Modul programmgesteuert zu importieren."importlib
stattdessen zu verwenden .Für Python <2.7 kann die integrierte Methode __ import__ verwendet werden:
__import__('abc.def.ghi.jkl.myfile.mymethod', fromlist=[''])
Für Python> = 2.7 oder 3.1 wurde die praktische Methode importlib.import_module hinzugefügt. Importieren Sie Ihr Modul einfach wie folgt:
importlib.import_module('abc.def.ghi.jkl.myfile.mymethod')
Update : Aktualisierte Version gemäß Kommentaren ( Ich muss zugeben, dass ich die zu importierende Zeichenfolge erst am Ende gelesen habe und die Tatsache übersehen habe, dass eine Methode eines Moduls importiert werden sollte und nicht ein Modul selbst) :
Python <2.7:
mymethod = getattr(__import__("abc.def.ghi.jkl.myfile", fromlist=["mymethod"]))
Python> = 2.7:
mymethod = getattr(importlib.import_module("abc.def.ghi.jkl.myfile"), "mymethod")
quelle
__import__()
undimportlib.import_module()
.Es ist unklar, was Sie mit Ihrem lokalen Namespace tun möchten. Ich nehme an, Sie wollen nur
my_method
als Einheimischer tippenoutput = my_method()
?# This is equivalent to "from a.b.myfile import my_method" the_module = importlib.import_module("a.b.myfile") same_module = __import__("a.b.myfile") # import_module() and __input__() only return modules my_method = getattr(the_module, "my_method") # or, more concisely, my_method = getattr(__import__("a.b.myfile"), "my_method") output = my_method()
Während Sie nur
my_method
den lokalen Namespace hinzufügen , laden Sie die Kette von Modulen. Sie können Änderungen anzeigen, indem Sie die Tastensys.modules
vor und nach dem Import beobachten. Ich hoffe, das ist klarer und genauer als Ihre anderen Antworten.Der Vollständigkeit halber fügen Sie auf diese Weise die gesamte Kette hinzu.
# This is equivalent to "import a.b.myfile" a = __import__("a.b.myfile") also_a = importlib.import_module("a.b.myfile") output = a.b.myfile.my_method() # This is equivalent to "from a.b import myfile" myfile = __import__("a.b.myfile", fromlist="a.b") also_myfile = importlib.import_module("a.b.myfile", "a.b") output = myfile.my_method()
Wenn Sie
__import__()
Ihren Suchpfad nach dem Start des Programms verwenden und geändert haben, müssen Sie ihn möglicherweise verwenden__import__(normal args, globals=globals(), locals=locals())
. Das Warum ist eine komplexe Diskussion.quelle
the_module
undsame_module
ist falsch und führt zu unterschiedlichen Ergebnissen. Downvoting.from importlib import import_module name = "file.py".strip('.py') # if Path like : "path/python/file.py" # use name.replaces("/",".") imp = import_module(name) # get Class From File.py model = getattr(imp, "classNameImportFromFile") NClass = model() # Class From file
quelle
.strip()
sich in dem von Ihnen angegebenen Fall nicht richtig verhält. Insbesondere wenn die Datei mit "py" beginnt, werden diese Zeichen ebenfalls entfernt. Zum Beispiel"pyfile.py".strip(".py")
produziert"file"
, wo es bevorzugt wäre, dass es"pyfile"
in diesem Fall produziert.name.replace(".py","")
funktioniert aber gut.Diese Website hat eine schöne Lösung: load_class . Ich benutze es so:
foo = load_class(package.subpackage.FooClass)() type(foo) # returns FooClass
Wie angefordert, ist hier der Code vom Weblink:
import importlib def load_class(full_class_string): """ dynamically load a class from a string """ class_data = full_class_string.split(".") module_path = ".".join(class_data[:-1]) class_str = class_data[-1] module = importlib.import_module(module_path) # Finally, we retrieve the Class return getattr(module, class_str)
quelle
Verwenden Sie
importlib
(nur 2.7+).quelle
from __future__
tun?__future__
ist für Sprachfunktionen, nicht für neue stdlib-Module.__import__
wie in den obigen Beispielen. Es funktioniert wieder auf 2.5 und davor ohne Schlüsselwörter.Die Art und Weise, wie ich dazu neige (sowie eine Reihe anderer Bibliotheken wie Pylone und Einfügen, wenn mein Speicher mir richtig dient), besteht darin, den Modulnamen vom Funktions- / Attributnamen zu trennen, indem ein ':' zwischen ihnen verwendet wird . Siehe folgendes Beispiel:
'abc.def.ghi.jkl.myfile:mymethod'
Dies
import_from(path)
erleichtert die Verwendung der folgenden Funktion.def import_from(path): """ Import an attribute, function or class from a module. :attr path: A path descriptor in the form of 'pkg.module.submodule:attribute' :type path: str """ path_parts = path.split(':') if len(path_parts) < 2: raise ImportError("path must be in the form of pkg.module.submodule:attribute") module = __import__(path_parts[0], fromlist=path_parts[1]) return getattr(module, path_parts[1]) if __name__=='__main__': func = import_from('a.b.c.d.myfile:mymethod') func()
quelle
Wie wäre es damit :
def import_module(name): mod = __import__(name) for s in name.split('.')[1:]: mod = getattr(mod, s) return mod
quelle