Decoriamo! – 3a puntata
Pubblicato da masci su 7 Maggio 2008
Dopo aver visto cosa sono i decorators in Python ed uno dei tanti modi di implementarli, approfondiamo l’argomento scrivendo un decorator un po’ più sofisticato, nella fattispecie uno che prenda un parametro:
def require(cond):
def decorator(func):
def wrapper(*args,**kw):
assert eval(cond),"Requirements failed"
return func(*args,**kw)
return wrapper
return decorator
@require("args[0] == 'admin'")
def login(*args):
print "Benvenuto, %s!" % args[0]
>>> login("admin", "123456")
Benvenuto, admin!
Ovviamente invocare login("masci", "6789") solleverà un assert.
In questo modo possiamo decorare la funzione login ogni qualvolta si voglia limitare l’accesso al solo utente “admin”. Il costrutto sintattico in questo caso prevede l’utilizzo di una closure, che è il decorator vero e proprio e che prende l’oggetto funzione come parametro (l’argomento passato nella def viene invece raccolto dalla funzione più esterna). Nell’esempio sopra ho aggiunto una terza closure (wrapper) che sostituisce col solito meccanismo la funzione login.
La tecnica di cui sopra apre interessanti prospettive, ad esempio potremmo decorare una funzione in modo da imporgli una certa lista di argomenti ed il valore di ritorno, o ancora aggiungere degli attributi a runtime.
UPDATE: C’era un errore sul codice del decoratore, grazie a Loris per la segnalazione!
RSS - Posts

Loris detto
ciao, complimenti per i tre articoli sui decoratori.
ma sull’ultimo manca la ‘func’ ?
masci detto
Sì, la funzione
.
decorator()prendeva un parametrofma poi nel corpo lo utilizzavo col nomefunc. Ovviamente non funzionavaGrazie per i complimenti e per la segnalazione!