Non v'è alcuna buona ragione per voler scrivere questo utilizzando un dizionario in Python. È strano e non è un modo comune per le funzioni dello spazio dei nomi.
Il filosofie Python applicabili qui:
Dovrebbe esserci tra-- e preferibilmente solo modo --obvious per farlo.
combinato con
Leggibilità conta.
Facendolo in questo modo rende anche le cose difficili da capire e leggere per il tipico utente Python.
Le cose buone del dizionario in questo caso sono le stringhe di mappa alle funzioni e lo spazio dei nomi all'interno di un dizionario, ma questa funzionalità è già fornita da entrambi i moduli e classi ed è molto più facile da capire da chi ha familiarità con Python.
Esempi: metodo
Modulo:
#cool.py
def cool():
print 'cool'
Ora usare il modulo come si sarebbe utilizzando il tuo dict: metodo
import cool
#cool.__dict__['cool']()
#update - to the more correct idiom vars
vars(cool)['cool']()
Classe:
class Cool():
def cool():
print 'cool'
#Cool.__dict__['cool']()
#update - to the more correct idiom vars
vars(Cool)['cool']()
Modifica dopo commento sotto:
argparse sembra una buona soluzione per questo problema, quindi non è necessario reinventare la ruota. Se decidi di implementarlo completamente da solo, anche se la fonte argparse dovrebbe darti una buona direzione. Ad ogni modo le sezioni seguenti sembrano applicabili a questo caso d'uso:
15.4.4.5. Oltre sys.argv
A volte può essere utile avere un argomento di analisi ArgumentParser diverso da quelli di sys.argv. Questo può essere ottenuto passando un elenco di stringhe in parse_args(). Ciò è utile per il test al prompt interattivo :
15.4.5.1. Sub-commands¶
ArgumentParser.add_subparsers()
Molti programmi divisi loro funzionalità in una serie di comandi secondari, per esempio, il programma svn può invocare comandi secondari come svn checkout, svn update, e svn commit.
15.4.4.6. L'oggetto Namespace
Potrebbe anche essere utile avere un ArgumentParser per assegnare attributi a un oggetto già esistente, piuttosto che un nuovo oggetto Namespace. Questo può essere raggiunto specificando il namespace = argomento chiave:
Update, ecco un esempio utilizzando argparse
strategizer = argparse.ArgumentParser()
strat_subs = strategizer.add_subparsers()
math = strat_subs.add_parser('math')
math_subs = math.add_subparsers()
math_max = math_subs.add_parser('max')
math_sum = math_subs.add_parser('sum')
math_max.set_defaults(strategy=max)
math_sum.set_defaults(strategy=sum)
strategizer.parse_args('math max'.split())
Out[46]: Namespace(strategy=<built-in function max>)
strategizer.parse_args('math sum'.split())
Out[47]: Namespace(strategy=<built-in function sum>)
Vorrei sottolineare le ragioni Suggerirei argparse
- Principalmente il requisito di utilizzare stringhe che rappresentano opzioni e opzioni secondarie per mappare le funzioni.
- È semplicissimo (dopo aver superato il modulo argparse pieno di funzioni).
- Utilizza un modulo di libreria standard Python. Questo fa sì che altri utenti familiarizzino con Python, senza sapere quali sono i tuoi dettagli di implementazione, ed è molto ben documentato per coloro che non lo sono.
- Molte funzionalità extra potrebbero essere sfruttate fuori dalla scatola (non la migliore ragione!).
Utilizzando argparse e strategia del modello insieme
Per l'attuazione puro e semplice del modello di strategia, questo è già stato risposto molto bene.
How to write Strategy Pattern in Python differently than example in Wikipedia?
#continuing from the above example
class MathStudent():
def do_math(self, numbers):
return self.strategy(numbers)
maximus = strategizer.parse_args('math max'.split(),
namespace=MathStudent())
sumera = strategizer.parse_args('math sum'.split(),
namespace=MathStudent())
maximus.do_math([1, 2, 3])
Out[71]: 3
sumera.do_math([1, 2, 3])
Out[72]: 6
Puoi spiegare perché vorresti farlo? Se vuoi recuperare un valore da una funzione, puoi inserirlo nel dizionario usando 'd ['function'] = my_func()'; se vuoi una funzione che non ti servirà mai più, potresti usare un 'lambda'. – Makoto
Un lambda non funziona per me, perché ho bisogno di istruzioni all'interno della funzione. La funzione non è banale. Voglio evitare di dichiarare la funzione se posso. Voglio la funzione dichiarata in linea. –
Come prevedete di essere in grado di utilizzare tutto ciò che non è definito al momento (non la posizione del file fisico) deve essere usato? Python definisce una funzione eseguendo un'istruzione 'def'. Python definisce il tuo dict eseguendo il tuo 'd = {etc etc etc}'. –