斐波那契数列巧用装饰器,functools.lru_cache是一个非常实用的装饰器。实现备忘功能,它会把后耗时的函数结果保存起来。避免传入相同的参数重复计算 LRU “ Least Recently Used ”表示缓存不会无限制增长,一段时间不用的缓存条目会被扔掉。
#clockdeco.py#简单的装饰器输出函数运行的时间import timedef clock(func):def clocked(*args):t0=time.perf_counter()result =func(*args)elapsed =time.perf_counter()-t0name =func.__name__arg_str =",".join(repr(arg) for arg in args)print('[%0.8fs] %s(%s) ->%r'%(elapsed,name,arg_str,result))return resultreturn clocked
#fino_demo.py"""生成第n个斐波那契数列,递归方式耗时"""from clockdeco import clock@clockdef fibonacci(n):if n <2:return nreturn fibonacci(n-2) +fibonacci(n-1)if __name__ =="__main__":print(fibonacci(6))
我们运行fibo_demo.py得到以下结果,除最后一行外,其他的都是clock装饰器生成。
![df26f552f24c3ea2e618802d4ddd700d.png](https://i-blog.csdnimg.cn/blog_migrate/4f60a5ebcf6d93086f4e36a06eac7974.jpeg)
fibo_demo.py运行结果
很明显看出 fibonacci(1)调用了8次,fibonacci(2)调用了5次
我们接下来将他改造 ,用lru_cache,改善性能,实现缓存
#fibo_demo.pyimport functools #导入functools from clockdeco import clock@functools.lru_cache() #加备忘,缓存 ,lru_cache可以接受配置参数@clock #叠放装饰器,@lru_cache() 应用到@clock返回的函数上def fibonacci(n):if n <2:return n return fibonacci(n-2) + fibonacci(n-1)if __name__ == '__main__':print(fibonacci(6))
我们执行上述函数,执行时间减半,n的每一个值只调用一次函数:
![1e865517639b990cbedf0a728fb27f1d.png](https://i-blog.csdnimg.cn/blog_migrate/aaa2ff65b46f6fd60489fe02bbd850db.jpeg)
lru_cache 除了优化递归函数之外,在web中获取信息的应用也能发挥作用。
lru_cache可以使用两个可选的参数配置
functools.lru_cache(maxsize=128,typed =False)
maxsize指数制定存储多少个调用结果,.缓存满之后,扔掉,腾出空间,maxsize应该设为2的幂。typed参数如果设置为True,把不同参数类型得到的结果分开保存,
#相等的整数浮点数去区分,lru_cache使用字典存储结果,键根据调用时传入的定位参数和关键字参数创建,lru_cache装饰甘薯,所有参数都必须时可散列的.