Sto imparando un po 'sui decoratori da un ottimo tutorial su thecodeship ma mi sono trovato piuttosto confuso da un esempio.Esempio di decoratore in pitone
Prima un semplice esempio seguito da una spiegazione per ciò che un decoratore è.
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
my_get_text = p_decorate(get_text)
print my_get_text("John")
Ora questo ha senso per me. Un decoratore è semplicemente un involucro per una funzione. E in questa spiegazione di ragazzi dice che un decoratore è una funzione che prende un'altra funzione come argomento, genera una nuova funzione e restituisce la funzione generata da usare ovunque.
E ora l'equivalente del codice di cui sopra è:
def p_decorate(func):
def func_wrapper(name):
return "<p>{0}</p>".format(func(name))
return func_wrapper
@p_decorate
def get_text(name):
return "lorem ipsum, {0} dolor sit amet".format(name)
print get_text("John")
Credo di capire il modo in cui un decoratore viene inizializzato quando somministrato senza argomenti. Correggimi se sbaglio
- Il decoratore di default passa nella funzione
get_text
e perchép_decorate
restituisce una funzionefunc_wrapper
, si finisce con l'affermazione veraget_text = func_wrapper
.
Ciò che è importante per me è il primo equivalente di codice, perché vedo e capisco come si comporta il decoratore.
La cosa che mi confonde molto è il seguente codice:
def tags(tag_name):
def tags_decorator(func):
def func_wrapper(name):
return "<{0}>{1}</{0}>".format(tag_name, func(name))
return func_wrapper
return tags_decorator
@tags("p")
def get_text(name):
return "Hello "+name
print get_text("John")
Anche in questo caso, mi corregga se sbaglio, ma questa è la mia comprensione.
- Il decoratore accetta la stringa di tag "p" al posto del nome della funzione di default . E a sua volta la funzione
tags_decorator
presuppone che il parametro che verrà passato sia la funzione decorata,get_text
.
Potrebbe essere utile per me vedere il blocco di codice equivalente in forma "non decoratore", ma non riesco a capire come potrebbe sembrare. Inoltre, non capisco perché sia restituito tags_decorator
e func_wrapper
. Qual è lo scopo di restituire due funzioni diverse se un decoratore deve solo restituire 1 funzione per avvolgere get_text
.
Come nota a margine, in realtà si riduce a quanto segue.
- Questo blocco può essere semplificato a qualcosa di meno di un insieme di 3 funzioni?
- I decoratori accettano più di 1 argomento per semplificare il codice?
Grazie. E ho fatto una breve modifica dopo la tua risposta. Perché esattamente queste serie di funzioni restituiscono 2 funzioni e non 1? – Max
@Max: vedere la mia ultima modifica. Uno è il decoratore (prodotto dalla fabbrica del decoratore), l'altro è l'involucro che sostituisce la funzione originale, il risultato del decoratore. –
Capisco ora, lo scopo delle 2 chiamate di funzione. Sono in grado di creare un decoratore specifico con la fabbrica di decorazioni per specificare ulteriormente il mio involucro finale. – Max