递归函数装饰器
Decorators for recursion function
我想编写一个装饰器来计算计算斐波那契数 5(fib(5)) 10 次的函数的运行时间,并打印一个中等运行时间值。但是我的装饰器 returns 出错了。如何解决这个问题?
import functools
import time
def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
total = 0
for i in range(times):
start = time.time()
func(*args, **kwargs)
end = time.time()
total += (end - start)
print('Medium value is {}'.format(total / times))
return func
return wrapper
return cache
@trace(times=10)
def fib(num):
if num < 2:
return num
return fib(num - 1) + fib(num - 2)
fib(5)
首先,在 wrapper
return 结果中 returning func
而不是
我们必须确保跟踪仅发生在对递归调用的 fib
和 none 的第一次调用中。让我们使用布尔值 traced
参数:
import functools
import time
def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, traced=True, **kwargs):
if not traced:
return func(*args, **kwargs)
total = 0
for i in range(times):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
total += (end - start)
print(f'run {i}, time is {total}')
print(f'Mean value is {total / times}')
return result
return wrapper
return cache
@trace(times=10)
def fib(num, traced=True):
if num < 2:
return num
return fib(num - 1, traced=False) + fib(num - 2, traced=False)
fib(5)
traced
默认为 True
,因此将跟踪对 fib(n)
的任何调用(用户无需注意 traced
参数)。但是递归调用都有 traced=False
因此它们不会触发装饰器中的循环。
我想编写一个装饰器来计算计算斐波那契数 5(fib(5)) 10 次的函数的运行时间,并打印一个中等运行时间值。但是我的装饰器 returns 出错了。如何解决这个问题?
import functools
import time
def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
total = 0
for i in range(times):
start = time.time()
func(*args, **kwargs)
end = time.time()
total += (end - start)
print('Medium value is {}'.format(total / times))
return func
return wrapper
return cache
@trace(times=10)
def fib(num):
if num < 2:
return num
return fib(num - 1) + fib(num - 2)
fib(5)
首先,在 wrapper
return 结果中 returning func
而不是
我们必须确保跟踪仅发生在对递归调用的 fib
和 none 的第一次调用中。让我们使用布尔值 traced
参数:
import functools
import time
def trace(times):
def cache(func):
@functools.wraps(func)
def wrapper(*args, traced=True, **kwargs):
if not traced:
return func(*args, **kwargs)
total = 0
for i in range(times):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
total += (end - start)
print(f'run {i}, time is {total}')
print(f'Mean value is {total / times}')
return result
return wrapper
return cache
@trace(times=10)
def fib(num, traced=True):
if num < 2:
return num
return fib(num - 1, traced=False) + fib(num - 2, traced=False)
fib(5)
traced
默认为 True
,因此将跟踪对 fib(n)
的任何调用(用户无需注意 traced
参数)。但是递归调用都有 traced=False
因此它们不会触发装饰器中的循环。