Costruire un codice basato su plugin in Python

1

Ho un programma che esegue azioni diverse a seconda dei plugin che vengono passati. Ad esempio, python main.py -m foo -m bar eseguirà le azioni di foo e bar .

La struttura della directory è:

├── Dockerfile
├── README.md
├── docker-compose.yml
├── entrypoint.sh
├── modules
│   └── foo.py
│   └── bar.py
├── main.py
├── requirements.txt
└── settings.yaml

E in main.py , ho una funzione per ciascuno dei plugin. Supponi quanto segue:

def foo():
    ...

def bar():
    ...

if args.all or 'foo' in args.modules:
    foo()
elif args.all or 'bar' in args.modules:
    bar()

Funziona, ma ci deve essere sicuramente un modo migliore per lavorare con i plugin, perché con l'aumentare del numero di moduli, con una funzione e un if per ognuno non sembra una buona opzione.

Qual è il modo consigliato di eseguire un'implementazione come questa?

    
posta yzT 13.12.2018 - 11:00
fonte

2 risposte

2

Se puoi inserire alcuni requisiti sui moduli, puoi renderlo piuttosto dinamico. I requisiti che devi inserire sui moduli sono almeno

  1. Il nome del file deve corrispondere al nome passato nell'argomento -m
  2. Il file deve essere inserito nella cartella modules/
  3. Il modulo deve supportare le funzioni che l'applicazione principale vorrà chiamare su di esso. Queste funzioni avranno un nome e argomenti come definiti dall'applicazione principale (quindi indipendenti dal modulo).

Con questi requisiti, puoi usare il modulo python importlib per caricare dinamicamente i tuoi moduli come moduli python e richiamarli su loro funzioni.
Per l'opzione --all , puoi semplicemente scorrere i file nella cartella modules/ .

    
risposta data 13.12.2018 - 13:24
fonte
1

Un'alternativa a più istruzioni if potrebbe essere una tabella di distribuzione:

modules = {
  'foo': foo,
  'bar': bar,
}

if args.all:
  args.modules = modules.keys()

for module_name in args.modules:
  try:
    module = modules[module_name]
  except KeyError:
    ...
  module()

Alcuni parser di argomenti della riga di comando come Click hanno il supporto integrato per l'esecuzione di più comandi, quindi non devi scrivere tu stesso questa logica di dispacciamento.

    
risposta data 13.12.2018 - 12:56
fonte

Leggi altre domande sui tag