尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Python内置的lru_cache装饰器实现缓存教程

Python内置的lru_cache装饰器实现缓存教程
📅 发布时间:2026/6/22 13:13:55

functools.lru_cache 是 Python 内置的函数缓存装饰器,基于「最近最少使用(LRU)」策略管理缓存,能自动缓存函数的调用结果,避免重复执行高耗时函数(如复杂计算、数据库查询)。以下是它的完整使用指南,包含基础用法、进阶技巧和注意事项。

一、核心原理

  • lru_cache 会记录函数的入参和对应的返回值,当函数以相同参数再次调用时,直接返回缓存的结果,无需重新执行函数。
  • 当缓存达到指定上限(maxsize),会自动淘汰「最近最少使用」的缓存条目,避免内存无限占用。

二、基础使用步骤

1. 导入模块

lru_cache 位于 functools 模块,需先导入:

from functools import lru_cache

2. 装饰函数

用 @lru_cache 装饰需要缓存的函数,核心参数:

参数 说明
maxsize 缓存的最大条目数(默认128;设为 None 表示无限制,禁用LRU淘汰)
typed 是否区分参数类型(默认False;设为True时,1 和 1.0 会被视为不同参数)

3. 基础示例:缓存复杂计算

from functools import lru_cache
import time# 装饰器:缓存函数结果,无缓存数量限制,不区分参数类型
@lru_cache(maxsize=None, typed=False)
def complex_calc(n):"""模拟耗时计算:计算n的阶乘(递归)"""time.sleep(1)  # 模拟1秒耗时if n == 0 or n == 1:return 1return n * complex_calc(n - 1)# 测试:首次调用(耗时)
start = time.time()
print(complex_calc(5))  # 输出120,耗时约5秒(递归5次,每次1秒)
print(f"首次调用耗时:{time.time() - start:.2f}秒")# 测试:重复调用(命中缓存,瞬间返回)
start = time.time()
print(complex_calc(5))  # 直接返回缓存结果120
print(f"缓存调用耗时:{time.time() - start:.2f}秒")

输出结果:

120
首次调用耗时:5.01秒
120
缓存调用耗时:0.00秒

三、常用进阶用法

1. 查看/清空缓存

lru_cache 为装饰后的函数提供了两个实用方法:

  • cache_info():返回缓存统计信息(命中数、未命中数、最大容量、当前缓存数);
  • cache_clear():清空所有缓存。

示例:

from functools import lru_cache@lru_cache(maxsize=10)
def add(a, b):return a + b# 调用函数,触发缓存
add(1, 2)
add(1, 2)
add(3, 4)# 查看缓存信息
print(add.cache_info())
# 输出:CacheInfo(hits=1, misses=2, maxsize=10, currsize=2)
# hits=1:1次命中;misses=2:2次未命中;currsize=2:当前缓存2条# 清空缓存
add.cache_clear()
print(add.cache_info())
# 输出:CacheInfo(hits=0, misses=0, maxsize=10, currsize=0)

2. 缓存带参数的数据库查询(模拟)

适合缓存「输入固定、输出固定」的查询操作,减少数据库访问:

from functools import lru_cache# 模拟数据库查询(高耗时操作)
def query_db(user_id):print(f"[数据库查询] user_id={user_id}")return {"id": user_id, "name": f"User{user_id}", "age": 20 + user_id}# 缓存查询结果(仅缓存可哈希参数)
@lru_cache(maxsize=100)
def get_user(user_id):return query_db(user_id)# 测试
print(get_user(1))  # 未命中,执行数据库查询
print(get_user(1))  # 命中缓存,直接返回
print(get_user(2))  # 未命中,执行数据库查询

输出:

[数据库查询] user_id=1
{'id': 1, 'name': 'User1', 'age': 21}
{'id': 1, 'name': 'User1', 'age': 21}
[数据库查询] user_id=2
{'id': 2, 'name': 'User2', 'age': 22}

3. 处理不可哈希参数(如列表/字典)

lru_cache 仅支持可哈希参数(如int、str、tuple),若函数参数是列表/字典(不可哈希),需先转为可哈希类型(如tuple):

from functools import lru_cache# 错误示例:参数为列表(不可哈希),会报错
# @lru_cache
# def sum_list(lst):
#     return sum(lst)# 正确示例:将列表转为元组(可哈希)
@lru_cache(maxsize=None)
def sum_list(lst_tuple):return sum(lst_tuple)# 调用时将列表转为元组
lst = [1, 2, 3]
print(sum_list(tuple(lst)))  # 6
print(sum_list(tuple(lst)))  # 命中缓存,直接返回

4. 区分参数类型(typed=True)

默认情况下 typed=False,1(int)和 1.0(float)会被视为相同参数;设为 typed=True 则区分类型:

from functools import lru_cache@lru_cache(typed=True)
def add(a, b):return a + bprint(add(1, 2))   # 未命中,返回3
print(add(1.0, 2.0))  # 未命中,返回3.0(typed=True,视为不同参数)
print(add.cache_info())  # hits=0, misses=2

四、关键注意事项

1. 仅适用于「纯函数」

lru_cache 缓存的是「入参→返回值」的映射,仅对纯函数(输入固定则输出固定,无副作用)有效:

  • ❌ 不适合带随机值、时间依赖、全局变量的函数(如 def get_time(): return time.time());
  • ❌ 不适合修改外部状态的函数(如操作数据库/文件的函数,除非仅查询)。

2. 避免缓存大对象/无限缓存

  • maxsize=None 会禁用LRU淘汰,缓存会无限增长,可能导致内存泄漏(适合少量固定参数的场景);
  • 避免缓存大对象(如超大列表、大字典),优先缓存小而高频的结果。

3. 程序重启后缓存丢失

lru_cache 是进程内内存缓存,程序重启/进程结束后缓存会清空,若需持久化/分布式缓存,需用 Redis 等工具。

4. 递归函数的缓存优化

lru_cache 对递归函数优化效果显著(如斐波那契数列),避免重复递归计算:

from functools import lru_cache@lru_cache(maxsize=None)
def fibonacci(n):if n <= 1:return nreturn fibonacci(n-1) + fibonacci(n-2)# 计算第50项(无缓存会卡死,有缓存瞬间返回)
print(fibonacci(50))  # 12586269025

五、总结

lru_cache 是 Python 最简单、最高效的内置缓存工具,核心用法:

  1. 导入 from functools import lru_cache;
  2. 装饰纯函数,通过 maxsize 控制缓存容量,typed 控制类型区分;
  3. 用 cache_info() 监控缓存命中率,cache_clear() 清空缓存;
  4. 仅缓存可哈希参数,不可哈希参数需先转换(如列表→元组)。

适合场景:单进程、无过期时间、纯函数的缓存需求;若需过期时间/分布式缓存,需用 cachetools/Redis 等扩展方案。

相关新闻

  • 北京墙体彩绘公司推荐香鲸艺术坊,行业排名遥遥领先!
  • java---gradle配置国内镜像
  • 11月25日日记

最新新闻

  • 如何利用Video2X实现AI驱动的视频画质无损提升
  • GEO排名优化服务商TOP8权威评测:2026年AI搜索排名提升指南 - GEORANK
  • 天津遗嘱咨询律所联系方式推荐 本地专业家事法律服务优选指南 - 外贸老黄
  • MuddyWater APT组织钓鱼攻击剖析与纵深防御实战指南
  • 生成式AI优化服务商TOP8盘点:2026年企业品牌AI认知提升指南 - GEORANK
  • 连续体机器人接触感知轨迹规划:从环境交互到智能控制

日新闻

  • Arduino-ESP32项目深度解析:解锁隐藏芯片支持与架构演进
  • 2026年 系统窗厂家/品牌推荐榜单:隔音系统窗+高端系统门窗的核心优势与选购指南 - 品牌发掘
  • NVBench:首个双语非言语发声语音合成评测基准详解与实践

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号