decoratori sono funzioni che funzioni di ritorno. Quando "passando un parametro al decoratore", ciò che stai facendo in realtà è chiamare una funzione che restituisce un decoratore. Quindi decAny()
dovrebbe essere una funzione che restituisce una funzione che restituisce una funzione.
Sarebbe simile a questa:
import functools
def decAny(tag):
def dec(f0):
@functools.wraps(f0)
def wrapper(*args, **kwargs):
return "<%s> %s </%s>" % (tag, f0(*args, **kwargs), tag)
return wrapper
return dec
@decAny('xxx')
def test2():
return 'test1XML'
Esempio:
>>> print(test2())
<xxx> test1XML </xxx>
Nota che, oltre a risolvere il problema specifico che si stavano colpendo Ho anche migliorato il codice un po 'con l'aggiunta di *args
e **kwargs
come argomenti per la funzione avvolta e passandoli sulla chiamata f0
all'interno del decoratore. In questo modo è possibile decorare una funzione che accetta un numero qualsiasi di argomenti posizionali o denominati e funzionerà comunque correttamente.
È possibile leggere su functools.wraps()
qui:
http://docs.python.org/2/library/functools.html#functools.wraps
fonte
2013-03-25 21:11:53
Pensare in questo modo: Prima ancora di _get_ per decorare 'test2', stai chiamando' decAny ('xxx') '. Ma 'decAny' prende una funzione,' f0', non una stringa. Quindi chiaramente ad un certo punto, che 'f0()' proverà a chiamare ''xxx''. – abarnert
Ok, ma come in un decoratore senza parametri perché il compilatore non assume che il primo parametro sia la funzione client ... – ZEE
Non è una questione di parametri. Se hai '@ decAny', è solo usando' decAny' stesso come decoratore. Ma se hai '@decAny()', si chiama 'decAny' prima ancora di arrivare alla decorazione, proprio come' @decAny ('xxx') 'è. (È proprio come quando passi le funzioni come valori, li memorizzi in variabili, ecc., Anziché chiamarli.) – abarnert