I Decoratori
I decoratori sono utili per modificare le funzioni utilizzando altre funzioni. Questa tecnica è utile quando hai bisogno di estendere le funzionalità di una funzione che non vuoi modificare.
def decoratore(func):
def wrap():
print("Estensione della funzione originale")
func()
return wrap
def saluta():
print("Hello World!")
deco = decoratore(saluta)
deco()
Eseguendo
>>>
Estensione della funzione originale
Hello World!
Il costrutto di un decoratore si basa sulla definizione di una funzione, il decoratore appunto, con una funzione come singolo argomento. Questa funzione sarà quella che vogliamo estendere di funzionalità. All’interno viene definita una funzione annidata che applica le estensioni da aggiungere insieme alla funzione originale. Alla fine restituisce la funzione annidata.
La variabile restituita, nell’esempio deco, non è altro che la funzione estesa, (o meglio decorata) che possiamo utilizzare da questo momento in poi come deco().
Questo pattern può essere utilizzato in qualsiasi momento per fare il wrapping di una funzione qualsiasi. Infatti Python fornisce una modalità di wrapping attraverso l’uso di un decorator (appunto) che viene messo prima della definizione di una funzione. I decoratori vengono indicati con il simbolo @.
Infatti scrivere
def decoratore(func):
def wrap():
print("Estensione della funzione originale")
func()
return wrap
@decoratore
def saluta():
print("Hello World!")
saluta()
è un modo più elegante e corretto di scrivere l’esempio precedente. Inoltre eseguendo possiamo vedere come saluta abbia modificato comportamento indipendentemente dalla sua definizione, ottenendo lo stesso risultato dell’esempio precedente.
Una funzione può avere più modificatori contemporaneamente.