Python中functools.lru_cache装饰器详解与实战应用
本文深入解析Python中functools模块提供的lru_cache装饰器,阐述其基于LRU(最近最少使用)算法的缓存机制。详细讲解maxsize和typed参数的配置方法及其对性能的影响,并通过对比普通调用与缓存调用的代码示例,展示如何避免重复计算。最后结合爬虫场景,演示如何利用该特性实现高效的网页请求去重与性能优化。
Python lru_cache基础示例
首先展示一段基础代码示例。
这是常规的函数调用方式。
def console1(a, b):
print("进入函数")
return (a, b)
print(console1(3, 'a'))
print(console1(2, 'b'))
print(console1(3.0, 'a'))
代码逻辑非常直观,主要接收两个参数并打印输出结果。具体的运行输出如下所示。
进入函数
(3, 'a')
进入函数
(2, 'b')
进入函数
(3.0, 'a')
引入lru_cache装饰器
接下来,我们在函数上应用一个特定的装饰器。
随后引入Python 3标准库中的functools模块,重点使用其中的lru_cache功能。
from functools import lru_cache
@lru_cache()
def console2(a, b):
print("进入函数")
return (a, b)
print(console2(3, 'a'))
print(console2(2, 'b'))
print(console2(3.0, 'a'))
观察结果可以发现明显的差异。
进入函数
(3, 'a')
进入函数
(2, 'b')
(3, 'a')
对比发现,函数内部打印语句的执行次数减少了一次。这种现象正是由LRU缓存技术所导致的,下面将详细解释其原理。
LRU算法原理与Python实现
我们需要先理解LRU的基本概念。
LRU(Least Recently Used,最近最少使用)是一种常用的缓存置换算法。当缓存空间已满且需要存入新元素时,系统必须移除现有队列中的一个元素。LRU策略的选择标准是移除“最近最少被访问”的元素,从而为新数据腾出空间。
在Python语言中的具体实现方式。
Python 3的functools模块通过lru_cache实现了这一功能。该装饰器会记录函数过往的运行结果,实现备忘(memoization)机制。当遇到相同参数时,直接返回缓存结果而不再次调用函数,从而提升性能,这在递归函数中效果尤为显著。本质上,这是一种优化技术,通过保存耗时函数的结果,避免相同参数下的重复计算。
lru_cache参数配置详解
lru_cache支持带参数的配置。
使用语法为lru_cache(maxsize=128, typed=False)。其中maxsize参数指定缓存的最大条目数,以提升程序执行效率,特别适合处理耗时函数。若maxsize设为None,则无数量限制;若设置为2的n次幂,通常能获得最佳性能。typed参数若设为True,则不同数据类型的参数调用将分别缓存(例如f(3)和f(3.0)被视为不同调用),默认值为False。以下是一段综合演示代码:
from functools import lru_cache
def console1(a, b):
print("进入函数")
return (a, b)
@lru_cache()
def console2(a, b):
print("进入函数")
return (a, b)
@lru_cache(maxsize=256, typed=True)
def console3(a, b):
'''
:param a:
:param b:
:return:
'''
print("进入函数")
return (a, b)
print(console1(3, 'a'))
print(console1(2, 'b'))
print(console1(3.0, 'a'))
print("*" * 40)
print(console2(3, 'a'))
print(console2(2, 'b'))
print(console2(3.0, 'a'))
print("*" * 40)
print(console3(3, 'a'))
print(console3(2, 'b'))
print(console3(3.0, 'a'))
实战应用:爬虫去重优化
该技术同样适用于爬虫场景中的去重操作,可有效避免对同一网页的重复请求。只需在数据存储阶段进行判断即可实现。
from functools import lru_cache
from requests_html import HTMLSession
session=HTMLSession()
@lru_cache()
def get_html(url):
req=session.get(url)
print(url)
return req
urllist=["https://www.baidu.com","https://pypi.org/project/pylru/1.0.9/","https://www.baidu.com"]
if __name__ == '__main__':
for i in urllist:
print(get_html(i))
上述代码的运行输出结果如下。
https://www.baidu.com
<Response [200]>
https://pypi.org/project/pylru/1.0.9/
<Response [200]>
<Response [200]>
以上内容涵盖了Python缓存技术的核心要点,希望能为读者提供有益参考,欢迎持续关注与支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









