While working on an XML-RPC server for App Engine, I came across an interesting problem. I wanted to add a way to get performance measurements for my calls, so I wrote a simple decorator that returns a tuple of the result and the time it took to complete.
from SimpleXMLRPCServer import CGIXMLRPCRequestHandlerThe key to making this work is functools.wraps(). Without it, the function returned by the decorator no longer has the same name as the original function. So, when I register the function, the call fails. You can fix this by hand (or pre 2.5) by changing your decorator like so:
import time
import functools
def timed(func):
@functools.wraps(func)
def decorator(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
return result, time.time() - start
return decorator
@timed
def mypow(*args):
return pow(*args)
if __name__ == '__main__':
handler = CGIXMLRPCRequestHandler()
handler.register_function(mypow)
handler.handle_request()
def timed(func):But functools.wraps() sets some additional attributes as well.
def decorator(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
return result, time.time() - start
decorator.__name__ = func.__name__
return decorator