Forum
>>
Principianti
>>
Overloading def
Pagina: 1 2 Avanti
Esegui il login per scrivere una risposta.
Scritto da Bibo90 |
2019-01-15 23:29:34 - Overloading def
|
Salve a tutti,
Volevo esporvi un mio quesito. Avrei la necessità di scrivere una funzione che ne wrapperizzi più di una, per capirci meglio una funzione che a seconda di un ingresso type='tipologia' esegua la funzione in un modo piuttosto che in un altro. Ad ogni stringa type possibile corrisponde una funzione di un secondo modulo (modulo che raccoglie tutte queste funzioni). Esiste un modo un po' più "carino" e meno ripetitivo rispetto alla classica pila di if type=="tipo" else (...). Magari con un dizionario? O sfruttando i __name__ delle def del modulo? Aggiungo inoltre che tale pila di if mi servirebbe per altre funzioni, dunque preferirei che se dovessi aggiungere una tipologia di comportamento (quindi aggiungere un funzione al modulo che le contiene) si cambiasse automaticamente in tutte le funzioni che wrapperizzano questi type. Grazie a tutti in anticipo |
|
Scritto da F _ |
2019-01-16 00:53:17 - Re: Overloading def
|
Scrivi un esempio, magari si capisce meglio
|
|
Scritto da Bibo90 |
2019-01-16 10:04:59 - Re: Overloading def
|
Certamente
minimizzando ai minimi termi una cosa del seguente tipo. Ovviamente le funzioni sono più di una che sfruttano mymodule quindi pensavo a una sorta di registro o sfruttando __name__ delle func non saprei. import mymodule def def1(x,y,type='a'): if type=='a': return mymodule.func_a(x,y) if type=='b': return mymodule.func_b(x,y) if type=='c': return mymodule.func_c(x,y) if type=='d': return mymodule.func_d(x,y) if type=='e': return mymodule.func_e(x,y) |
|
Scritto da RicPol |
2019-01-16 10:11:45 - Re: Overloading def
|
Quello che cerchi di fare è un'elementare strategia di dispatching. Ora, si può andare nel sofisticato (strategy pattern, observer pattern... al massimo prova a googlare un po') ma in pratica la cosa più naturale, in python, è usare un dizionario (dictionary-based dispatch). Qualcosa come:
def f1(a, b, c): pass def f2(a, b, c): pass def f3(a, b, c): pass DISPATCH_TABLE = {'foo!': f1, 'bar!': f2, 'baz!': f3} def f(operation, a, b, c): return DISPATCH_TABLE[operation](a, b, c) # quindi adesso # f('bar!', 1, 2, 3) # esegue f2(1, 2, 3)Questo pattern è la risposta standard che si dà (dall'alba dei tempi) a tutti quelli che provengono da un linguaggio con un qualche tipo di switch statement e che ne sentono la mancanza in Python. Ovviamente la cosa funziona se (come nel mio esempio) tutte le funzioni "figlie" hanno la stessa signature, che si può raccogliere tal quale nella funzione "madre". Se le funzioni hanno signature diverse, allora magari puoi fare dei trucchi con *args e/o **kwargs, ma prima chiediti se ha davvero senso raggrupparle insieme, se sono così diverse. Ancora una cosa: NON usare "type" nel tuo codice. "Type" è una builtin function in python, e non prendere l'abitudine di sovrascriverla, anche nei casi in cui non è dannoso farlo, come questo. --- Ultima modifica di RicPol in data 2019-01-16 10:12:15 --- https://pythoninwindows.blogspot.com/p/i-miei-libri.html : i miei libri
https://pythoninwindows.blogspot.com : il mio blog |
|
Scritto da Bibo90 |
2019-01-16 10:22:24 - Re: Overloading def
|
davvero chiarissimo la soluzione penso sia perfetta per il mio caso!
si le funzioni hanno tutte stesso ingresso e stessa uscita cambiando solo le operazioni all'interno quindi la soluzione che mi hai proposto penso sia ottima. grazie mille! |
|
Scritto da ㎝ |
2019-01-16 11:49:19 - Re: Overloading def
|
Se non vuoi dover tenere allineata la DISPATCH_TABLE e il modulo, e se le funzioni hanno una naming convention comune, puoi anche fare qualcosa tipo:
$ cat mymodule.py def func_a(x, y): ... def func_b(x, y): ... def func_c(x, y): ... def func_d(x, y): ... def func_e(x, y): ... $ py >>> import mymodule >>> def def1(x, y, type_='a'): return getattr(mymodule, 'func_' + type_)(x, y) ... >>> def1(1, 2, 'c') HTH, ㎝ THE 🍺-WARE LICENSE (Revision ㊷):
<㎝🐌🐍.🇮🇹> wrote this post. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a 🍺 in return. -- ㎝ |
|
Scritto da Bibo90 |
2019-01-16 12:01:29 - Re: Overloading def
|
ottima idea! si sarebbe davvero comodo che aggiungendo la sola func al modo si aggiornino tutte le funzioni! faccio qualche tentativo e vi farò sapere
--- Ultima modifica di Bibo90 in data 2019-01-16 12:03:17 --- |
|
Scritto da RicPol |
2019-01-16 12:25:33 - Re: Overloading def
|
> Se non vuoi dover tenere allineata la DISPATCH_TABLE e il modulo, e se
le funzioni hanno una naming convention comune, puoi anche fare qualcosa tipo ... Questa è veramente una cattiva idea, stanne alla larga. E anche se non fosse una cattiva idea (e lo è), tieni conto che tecnicamente questo non è più "semplice" dispatching, è già metaprogrammazione/code inspection. Ora, fare code inspection può essere utile e necessario in certi scenari, ma è una bestia di un altro tipo. --- Ultima modifica di RicPol in data 2019-01-16 12:25:57 --- https://pythoninwindows.blogspot.com/p/i-miei-libri.html : i miei libri
https://pythoninwindows.blogspot.com : il mio blog |
|
Scritto da Bibo90 |
2019-01-16 12:25:35 - Re: Overloading def
|
tuttavia mi sorge un dubbio, essendo che il modulo "mymodule" una volta terminata la fase di prototipazione sarà compilato in cython, la funzione getattr funzionerà ugualmente o potrebbe dare dei problemi?
|
|
Scritto da RicPol |
2019-01-16 13:28:45 - Re: Overloading def
|
getattr dovrebbe funzionare senza problemi in cython. Posto che usare getattr nel tuo scenario è una cattiva idea, come detto.
https://pythoninwindows.blogspot.com/p/i-miei-libri.html : i miei libri
https://pythoninwindows.blogspot.com : il mio blog |
Pagina: 1 2 Avanti
Esegui il login per scrivere una risposta.