Perché i seguenti due script non sono equivalenti?Perché i decoratori Python non possono essere concatenati tra le definizioni?
(Tratto da un'altra domanda: Understanding Python Decorators)
def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
@makebold
@makeitalic
def hello():
return "hello world"
print hello() ## returns <b><i>hello world</i></b>
e con un decoratore decorato:
def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
@makebold
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
@makeitalic
def hello():
return "hello world"
print hello() ## TypeError: wrapped() takes no arguments (1 given)
Perché voglio sapere? Ho scritto un decoratore retry
per catturare le eccezioni MySQLdb - se l'eccezione è transitoria (ad es. Timeout) richiamerà la funzione dopo aver dormito un po '.
Ho anche un decoratore modifies_db
che si occupa di alcune operazioni di pulizia relative alla cache. modifies_db
è decorato con retry
, quindi ho presupposto che tutte le funzioni decorate con modifies_db
riprovassero implicitamente. Dove ho sbagliato?
Buona domanda. Mi sono imbattuto nello stesso scenario pochi mesi fa mentre facevo il mio decoratore di nuovi tentativi. Ci sono voluti un conteggio dei tentativi, quindi il problema si presentava un po 'diverso dal tuo, ma aveva le stesse soluzioni viste di seguito. –