@lru_cache适用于纯函数的性能优化,基于LRU策略缓存结果;需满足参数可哈希、无副作用、不依赖外部状态,并合理设置maxsize以防内存膨胀。

@lru_cache 是 Python 标准库 functools 中提供的轻量级函数结果缓存装饰器,适用于**纯函数**(即相同输入总返回相同输出、无副作用)的性能优化场景。它基于最近最少使用(LRU)策略管理缓存,避免重复计算,尤其对递归、高频调用或耗时计算类函数效果显著。
什么时候该用 @lru_cache?
以下情况建议启用:
- 函数被频繁调用,且参数组合有限(如斐波那契数列、树形结构遍历、解析固定格式字符串)
- 函数内部有较重计算(如数值迭代、小规模查表、正则匹配预处理)但不涉及 I/O、全局状态或随机性
- 你已确认函数是纯的——不修改外部变量、不依赖时间/文件/网络等外部状态
- 内存可控:缓存容量默认不限(
maxsize=None),但实际应设合理上限(如@lru_cache(maxsize=128))防止内存膨胀
基础用法与常见配置
最简写法:
from functools import lru_cache
@lru_cache()
def fib(n):
if n
return n
return fib(n-1) + fib(n-2)
立即学习“Python免费学习笔记(深入)”;
关键参数说明:
-
maxsize:缓存最大条目数。设为None表示无限制;设为整数(如128)启用 LRU 驱逐;设为0相当于禁用缓存(仅用于调试开关) -
typed:是否区分参数类型(如fib(1)和fib(1.0)是否视为不同调用)。默认False;设为True可提升类型敏感场景的准确性,但略增开销
必须注意的限制和陷阱
@lru_cache 不是万能加速器,踩坑点包括:
-
不可缓存可变参数:若函数接受
list、dict等可变对象作为参数,会直接报TypeError: unhashable type。解决方法是转成tuple或frozenset,或改用其他缓存方案(如functools.cached_property或手动字典缓存) - 不跟踪内部状态变化:若函数依赖外部变量(如全局计数器、配置字典),缓存结果可能过期却不会自动更新
-
线程安全但非进程安全:同一进程中多线程共享缓存,但多进程间不共享——需用
multiprocessing.Manager或 Redis 等外部缓存替代 - 无法缓存异常:抛出异常的调用不会被缓存,每次都会重新执行
查看和管理缓存状态
装饰后函数会新增两个实用方法:
-
func.cache_info():返回命名元组CacheInfo(hits, misses, maxsize, currsize),可用于监控命中率 -
func.cache_clear():清空当前缓存,适合在配置变更、数据刷新后手动重置
例如:
print(fib.cache_info()) # CacheInfo(hits=98, misses=10, maxsize=128, currsize=10)
fib.cache_clear()










