Python 函数装饰器调用
我有一个函数大约被调用了1742次,但当我用一个装饰器来计算每次调用的时间时,发现它只打印了647次,我不知道为什么会这样。
更新:
我这里的问题不是如何计时,而是调用次数之间的差异。我想要一个能准确记录调用次数的装饰器函数。
我的Python版本是2.6,这里是我正在使用的模块 http://pastebin.com/MXu1pLWM
在性能分析的输出中,我发现调用被装饰函数的调用者函数只调用了它647次,而它是唯一的调用者函数!!
搞明白了!
我装饰的函数里面有一个长度为1742的循环,但实际上对这个函数的调用只有647次,尽管我还是不明白为什么调用部分显示的是1742而不是647 :)
number = 0
def timing(f):
def wrap(*args):
time1 = time.time()
ret = f(*args)
time2 = time.time()
global number
number+=1
print '%s function took %0.6f ms No of calls: %s' % (f.func_name, ((time2-time1)), str(number))
return ret
return wrap
1 个回答
5
我看了你在pastebin上贴的代码。问题在于你把一个类的__iter__
方法包裹起来了。这个方法每次循环开始时只会被调用一次。它应该立即返回一个迭代器对象——真正需要分析的是对__iter__
返回的对象上调用“next”方法的次数(这个方法在每次for
循环中都会被调用)。
这意味着,如果不做任何改动,你应该把你的分析工具用在__iter__
内部的yield
语句周围,而不是把它当作装饰器用在__iter__
的调用上。
除此之外,使用timeit.timeit
或者其他现成的分析工具会更好,这样可以避免一些常见的陷阱,评论中也列出了这些陷阱。