Why arn't the following two scripts equivalent?
(Taken from another question: 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>
and with a decorated decorator:
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)
Why do I want to know? I've written a retry
decorator to catch MySQLdb exceptions - if the exception is transient (e.g. Timeout) it will re-call the function after sleeping a bit.
I've also got a modifies_db
decorator which takes care of some cache-related housekeeping. modifies_db
is decorated with retry
, so I assumed that all functions decorated with modifies_db
would also retry implicitly. Where did I go wrong?