Ich schreibe eine Python-Anwendung, die z. B. einen Befehl als Argument annimmt:
$ python myapp.py command1
Ich möchte, dass die Anwendung erweiterbar ist, d. h., dass neue Module hinzugefügt werden können, die neue Befehle implementieren, ohne dass der Hauptanwendungscode geändert werden muss. Der Baum sieht in etwa so aus:
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
Ich möchte also, dass die Anwendung zur Laufzeit die verfügbaren Befehlsmodule findet und das entsprechende Modul ausführt.
Python definiert eine __import__()
Funktion, die eine Zeichenkette als Modulnamen annimmt:
__import__(name, globals=None, locals=None, fromlist=(), level=0)
Die Funktion importiert das Modul
name
möglicherweise unter Verwendung der angegebenenglobals
etlocals
um zu bestimmen, wie der Name in einem Paketkontext zu interpretieren ist. Diefromlist
gibt die Namen von Objekten oder Untermodulen an, die aus dem Modul importiert werden sollen, das durchname
.Quelle: https://docs.python.org/3/library/functions.html#__import_ _
Derzeit habe ich also etwas wie:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
Dies funktioniert sehr gut, ich frage mich nur, ob es möglicherweise eine idiomatischere Weise zu erreichen, was wir mit diesem Code tun.
Beachten Sie, dass ich ausdrücklich nicht auf die Verwendung von Eiern oder Verlängerungspunkten eingehen möchte. Dies ist kein Open-Source-Projekt und ich erwarte nicht, dass es "Plugins" gibt. Es geht darum, den Hauptanwendungscode zu vereinfachen und ihn nicht jedes Mal ändern zu müssen, wenn ein neues Befehlsmodul hinzugefügt wird.
0 Stimmen
Was bewirkt die fromlist=["myapp.commands"]?
2 Stimmen
@PieterMüller : Geben Sie in einer Python-Shell Folgendes ein:
dir(__import__)
. Die fromlist sollte eine Liste von Namen sein, um "from name import ..." zu emulieren.4 Stimmen
Modul aus String-Variable importieren
1 Stimmen
Ab 2019 sollten Sie auf Folgendes achten
importlib
: stackoverflow.com/a/54956419/6878961 Stimmen
Verwenden Sie nicht __import__ siehe Python-Doku ein verwenden importlib.import_module