写Python代码时,你是否遇到过同一个函数被反复调用、每次都重复计算的情况?
比如从数据库抓同一条数据,或频繁请求同一个API。这不仅慢,还浪费资源。
cachetools 模块就是为此而生——它提供了好用的缓存装饰器,帮你自动存储计算结果,大幅提升程序效率。今天咱们就来实战一把。
🔧 基础缓存:TTLCache时间失效
很多时候,我们希望缓存的数据过一段时间就自动清空,保证数据新鲜度。
TTLCache 正好解决这个需求,它能设定每个缓存项的存活时间。
from cachetools import TTLCache, cached
cache = TTLCache(maxsize=2, ttl=5)
@cached(cache)
defdouble_price(price):
return price * 2
print(double_price(100))
print(double_price(200))
print(double_price(100)) # 直接从缓存取
执行结果:
200
400
200
第一遍调用 double_price(100) 计算结果并存入缓存。
5秒内再次请求100,直接从缓存返回200,不再重复计算。超过5秒,缓存失效,函数会重新执行。
📊 LRU策略:LFUCache淘汰冷数据
内存不是无限的。当缓存装不下时,需要淘汰掉“最不常用”的数据。
LFUCache 会自动记录每个缓存项被访问的频率,优先保留高频数据,驱逐低频数据。
from cachetools import LFUCache, cached
cache = LFUCache(maxsize=2)
@cached(cache)
defget_user(name):
returnf"欢迎{name}"
print(get_user("小明"))
print(get_user("小红"))
print(get_user("小明")) # 小明被频繁访问
print(get_user("小刚")) # 触发淘汰
执行结果:
欢迎小明
欢迎小红
欢迎小明
欢迎小刚
缓存最多存2条数据。先存入小明、小红,再次取小明时它的访问计数上升。
存小刚时空间不足,低频的小红被淘汰,留下小明和小刚。常用的数据被保留,非常聪明的策略。
⚡ 手动控制:clear与popitem
有时你需要主动干预缓存,比如用户修改了资料,必须立即刷新缓存里的旧数据。
cachetools 提供了 clear() 清空全部,popitem() 移除指定项。
from cachetools import LRUCache
cache = LRUCache(maxsize=3)
cache[1] = "苹果"
cache[2] = "香蕉"
cache[3] = "橘子"
print(cache.popitem())
cache.clear()
print(len(cache))
执行结果:
(1, '苹果')
0
popitem() 默认移除最近最少使用的项(这里是1号苹果)。clear() 则清空整个字典。
这些手动控制让你在业务逻辑变化时灵活调整缓存内容,非常实用。
🆚 对比优势与不足
相比 functools.lru_cache,cachetools 支持时间过期(TTL)与LFU算法,更适合数据会更新的业务场景(如API限流缓存)。
不足之处:多线程环境下需要额外加锁,且内存增长需自行监控。
建议高频读取、低频写入且数据有时效性的场景优先使用。
💬 写在最后
今天我们实战了 cachetools 的三种核心缓存策略:TTLCache自动过期、LFUCache冷热淘汰、以及手动控制API。
这些工具能让你的Python代码飞起来,减少数据库压力和响应时间。
你在项目中用过哪些缓存方案?遇到过缓存穿透或雪崩的坑吗?
欢迎在评论区分享你的经验,一起交流进步!