Decoriamo! – 3a puntata

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!

2 thoughts on “Decoriamo! – 3a puntata

  1. Sì, la funzione decorator() prendeva un parametro f ma poi nel corpo lo utilizzavo col nome func. Ovviamente non funzionava😉.
    Grazie per i complimenti e per la segnalazione!

Comments are closed.