Warum sind die folgenden beiden Skripte nicht äquivalent?Warum können Python-Dekoratoren nicht über Definitionen hinweg verkettet werden?
(aus einer anderen Frage Genommen: 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>
und mit einem verzierten Dekorateur:
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)
Warum will ich wissen? Ich habe einen retry
Dekorator geschrieben, um MySQLdb-Ausnahmen zu fangen - wenn die Ausnahme vorübergehend ist (z. B. Timeout), wird sie die Funktion nach dem Einschlafen erneut aufrufen.
Ich habe auch einen modifies_db
Dekorateur, der sich um einige Cache-bezogene Housekeeping kümmert. modifies_db
ist mit retry
dekoriert, so nahm ich an, dass alle mit modifies_db
verzierten Funktionen auch implizit wiederholen würden. Was habe ich falsch gemacht?
Gute Frage. Ich bin vor ein paar Monaten in dasselbe Szenario geraten, als ich meinen eigenen Retry Decorator gemacht habe. Es dauerte eine Wiederholung, so dass das Problem ein wenig anders als bei Ihnen vorkam, aber die gleichen Lösungen wie unten gezeigt hatte. –