这是我定义定时装饰器的代码:
from functools import wraps, lru_cache
def timed(fn):
from time import perf_counter
@wraps(fn)
def inner(*args,**kwargs):
start = perf_counter()
result = fn(*args,**kwargs)
end = perf_counter()
timer = end - start
fs = '{} took {:.3f} microseconds'
print(fs.format(fn.__name__, (end - start) * 1000000))
return result
return inner
这是函数定义:
@timed
@lru_cache
def factorial(n):
result = 1
cache = dict()
if n < 2:
print('Calculating factorial for n > 1')
result = 1
print(f'factorial of {result} is {result}')
else:
for i in range(1,n+1):
if i in cache.items():
result = cache[i]
#print(f'factorial of {i} is {result}')
else:
result *= i
cache[i] = result
print(f'factorial of {i} is {result}')
#print(f'{cache}')
return result
以下是对函数的调用:
阶乘(3)
阶乘(10)
阶乘(10)
这是输出
factorial of 3 is 6
factorial took 32.968 microseconds
factorial of 10 is 3628800
factorial took 11.371 microseconds
**factorial took 0.323 microseconds**
问题: 为什么当我第二次调用factorial(10)时,没有打印输出?
答案 0 :(得分:2)
因为lru_cache
的全部要点是缓存函数的参数和与它们关联的返回值,并最小化装饰函数的实际执行次数。
当您第二次调用factorial(10)
时,不会调用该函数,而是从缓存中获取该值。这也是为什么第二次调用快 35倍的原因-因为甚至没有调用该函数,而这正是functools.lru_cache
的目的。
答案 1 :(得分:1)
您只想缓存 pure 函数;您的阶乘不纯,因为它有写入标准输出的副作用。
对于所需的行为,请定义两个函数:您缓存的纯函数和使用该纯函数的不纯包装。
@lru_cache
def factorial_math(n):
result = 1
for i in range(2, n):
result *= i
return result
@timed
def factorial(n):
result = factorial_math(n)
print(f'factorial of {n} is {result}')
return result