我有一个简单的装饰器,用于跟踪函数调用的运行时间:
def timed(f):
def caller(*args):
start = time.time()
res = f(*args)
end = time.time()
return res, end - start
return caller
这可以如下所示使用,并返回函数结果和执行时间的元组。
@timed
def test(n):
for _ in range(n):
pass
return 0
print(test(900)) # prints (0, 2.69e-05)
很简单。但是现在我想将其应用于递归函数。将上述包装器应用于递归函数会产生嵌套的元组,其中包含每个递归调用的次数,这是预期的结果。
@timed
def rec(n):
if n:
return rec(n - 1)
else:
return 0
print(rec(3)) # Prints ((((0, 1.90e-06), 8.10e-06), 1.28e-05), 1.90e-05)
有什么优雅的方法可以编写装饰器,以便它正确处理递归?显然,如果是一个定时函数,你可以包装调用:
@timed
def wrapper():
return rec(3)
这将返回一个结果和时间的元组,但我希望装饰器来处理所有内容,这样调用者就不必担心为每个调用定义一个新函数。有什么好的想法吗?
sys._getframe
来实现您想要的功能,但这是CPython的一个实现细节,因此它不是Python语言的真正一部分。此外,它可能会很慢。 - Bakuriu