Sto scrivendo un'applicazione Python che accetta come comando come argomento, ad esempio:
$ python myapp.py command1
Voglio che l'applicazione sia estensibile, cioè per poter aggiungere nuovi moduli che implementano nuovi comandi senza dover cambiare l'origine dell'applicazione principale. L'albero è simile a:
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
Quindi voglio che l'applicazione trovi i moduli di comando disponibili in fase di esecuzione ed esegua quello appropriato.
Python definisce una funzione __import__ , che accetta una stringa per il nome di un modulo:
__import __ (nome, globali = Nessuno, locali = Nessuno, dalla lista = (), livello = 0)
La funzione importa il nome del modulo, utilizzando potenzialmente i globali e i locali indicati per determinare come interpretare il nome in un contesto di pacchetto. La fromlist fornisce i nomi di oggetti o sottomoduli che dovrebbero essere importati dal modulo dato dal nome.
Fonte: https://docs.python.org/3/library/functions.html# import
Quindi attualmente ho qualcosa del tipo:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
Funziona bene, mi chiedo solo se esiste forse un modo più idiomatico per realizzare ciò che stiamo facendo con questo codice.
Nota che non voglio specificamente usare uova o punti di estensione. Questo non è un progetto open source e non mi aspetto che ci siano "plugin". Il punto è semplificare il codice principale dell'applicazione e rimuovere la necessità di modificarlo ogni volta che viene aggiunto un nuovo modulo di comando.
dir(__import__)
. La fromlist dovrebbe essere una lista di nomi da emulare "dall'importazione dei nomi ...".
importlib
: stackoverflow.com/a/54956419/687896