Decorator question: prefer class, but only function works

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Nov 14 22:22:03 EST 2011


On Mon, 14 Nov 2011 17:00:38 -0800, Russell E. Owen wrote:

> Oops, I stripped so much out of my example that I stripped the ugly bit.
> This is closer to the original and demonstrated the issue:
> 
> def timeMethod(func):
>     name = func.__name__ + "Duration"
>     def wrapper(self, *args, **keyArgs):
>        t1 = time.time()
>        res = func(self, *args, **keyArgs)
>        duration = time.time() - t1
>        self.timings[name] = duration
>        return res
>    return wrapper
> 
> I don't like the way name is passed into wrapper. It works, but it looks
> like magic. A class offers an obvious place to save the information. Or
> I could just generate the name each time.

The pattern you are seeing is called a closure, and it is a very 
important, if advanced, part of Python programming. Of course, you don't 
*have* to use closures, but it isn't scarily-advanced (like metaclass 
programming) but only moderately advanced, and there will be a lot of 
code out there using closures.

http://en.wikipedia.org/wiki/Closure_(computer_science)

Basically a closure is a function which remembers just enough of its 
current environment (the value of non-local variables) so that it can 
continue to work in the future, even if those non-locals change or 
disappear.

I take it you are aware that timing code as shown is only suitable for 
long-running code, and not small snippets? For small snippets, you should 
use the timeit module.

You might also find this recipe useful:

http://code.activestate.com/recipes/577896/



-- 
Steven



More information about the Python-list mailing list