On Thu, Nov 10, 2011 at 2:52 PM, Russell E. Owen <ro...@uw.edu> wrote: > I am trying to write a decorator that times an instance method and > writes the results to a class member variable. For example: > > def timeMethod(func): > def wrapper(self, *args, **keyArgs): > t1 = time.time() > res = func(self, *args, **keyArgs) > duration = time.time() - t1 > self.timings[func.__name__] = duration > return res > return wrapper > > This works, but I'm not very happy with the way self.timings is obtained.
What do you feel is wrong with it? You probably should use sum(os.times()[:2]) instead, which (assuming your script is single-threaded) will more accurately count the actual CPU time spent in the function rather than real time, which could be quite different if the CPU is busy. Also, why do you need this? If you're just trying to evaluate the speed of your code, you should consider using a proper profiler or the timeit module. The former will tell you how much time is spent in each function, while the latter runs the code a large number of times in a loop, which gives you better precision for quick methods. > I first tried to write this as a class (for readability), and this did > NOT work: > > class timeMethod(object): > def __init__(self, func): > self.func = func > def __call__(self, *args, **keyArgs): > t1 = time.time() > res = self.func(*args, **keyArgs) > duration = time.time() - t1 > args[0].timings.set(self.func.__name__, duration) > return res > > In the first case the wrapper is called as an unbound function, so it > works. But in the second case the wrapper is called as a bound method -- > thus args[0] is not func's class instance, and I can't get to the > timings attribute. I prefer the function version myself, but to make this work you could add something like this (untested) to make your wrapper class a descriptor that tacks on the self argument: def __get__(self, instance, owner): from functools import partial if instance is None: return self return partial(self, instance) HTH, Ian -- http://mail.python.org/mailman/listinfo/python-list