Python本地缓存案例如何实现?

wen python案例 1

本文目录导读:

  1. 最简单的:字典缓存(手动实现)
  2. 带过期时间的缓存(TTL)
  3. 使用 functools.lru_cache(标准库,最推荐)
  4. 使用第三方库 cachetools(功能最丰富)
  5. 使用 diskcache(持久化到磁盘,进程重启不丢失)
  6. 总结:如何选择?

Python 实现本地缓存的案例非常多,根据你的需求复杂度不同,可以从最简单的字典缓存到使用标准库 functools.lru_cache,再到使用第三方库如 cachetoolsdiskcache

下面我为你整理了 5种不同场景的本地缓存实现案例,从简单到复杂,覆盖内存缓存和磁盘缓存。


最简单的:字典缓存(手动实现)

适用场景:临时存储少量数据,进程退出即失效。

import time
# 全局缓存字典
cache = {}
def get_data_from_database(key):
    """模拟一个耗时的数据库查询"""
    print(f"  正在查询数据库: {key}")
    time.sleep(2)  # 模拟耗时
    return f"数据_{key}"
def get_data(key):
    """带缓存的获取函数"""
    if key not in cache:
        cache[key] = get_data_from_database(key)
    else:
        print(f"  缓存命中: {key}")
    return cache[key]
# 测试
print(get_data("user_1"))  # 第一次,查询数据库
print(get_data("user_1"))  # 第二次,缓存命中

输出

  正在查询数据库: user_1
数据_user_1
  缓存命中: user_1
数据_user_1

带过期时间的缓存(TTL)

适用场景:数据需要定期刷新,比如从API获取的token或天气数据。

import time
class TTLCache:
    def __init__(self, ttl_seconds=10):
        self.cache = {}
        self.ttl = ttl_seconds
    def get(self, key):
        """获取缓存,如果过期返回None"""
        if key in self.cache:
            value, timestamp = self.cache[key]
            if time.time() - timestamp < self.ttl:
                return value
            else:
                del self.cache[key]  # 删除过期数据
        return None
    def set(self, key, value):
        self.cache[key] = (value, time.time())
# 使用示例
cache = TTLCache(ttl_seconds=5)
# 模拟存储
cache.set("weather", "晴天")
print(cache.get("weather"))  # 输出: 晴天
time.sleep(6)  # 等待超过5秒
print(cache.get("weather"))  # 输出: None(过期了)

使用 functools.lru_cache(标准库,最推荐)

适用场景:对纯函数进行缓存,计算密集型任务(如斐波那契、递归、复杂计算)。

from functools import lru_cache
import time
@lru_cache(maxsize=128)  # 最多缓存128个结果
def expensive_computation(n):
    """模拟一个耗时的计算"""
    print(f"  正在计算 {n}...")
    time.sleep(1)
    return n * n
# 测试
print(expensive_computation(5))  # 计算,输出25
print(expensive_computation(5))  # 直接返回缓存,不打印"正在计算"
print(expensive_computation(10)) # 计算新值

关键特性

  • maxsize:缓存大小,设为 None 则无限制(小心内存溢出)
  • LRU(Least Recently Used)淘汰策略:当缓存满时,淘汰最久未使用的数据
  • 函数参数必须可哈希(不可用list、dict作为参数)

查看缓存状态

print(expensive_computation.cache_info())
# 输出: CacheInfo(hits=1, misses=2, maxsize=128, currsize=2)

使用第三方库 cachetools(功能最丰富)

适用场景:需要TTL、不同淘汰策略(LFU、FIFO、LRU)、更精细控制。

安装:

pip install cachetools

案例:带TTL的缓存

from cachetools import TTLCache
import time
# 创建缓存:最大容量100,TTL 10秒
cache = TTLCache(maxsize=100, ttl=10)
# 像字典一样使用
cache["key1"] = "value1"
print(cache["key1"])  # 输出: value1
time.sleep(11)
print("key1" in cache)  # 输出: False(过期了)

不同淘汰策略

from cachetools import LRUCache, LFUCache, FIFOCache
# LRU: 最近最少使用(推荐通用)
lru_cache = LRUCache(maxsize=100)
# LFU: 使用频率最少
lfu_cache = LFUCache(maxsize=100)
# FIFO: 先进先出
fifo_cache = FIFOCache(maxsize=100)

使用 diskcache(持久化到磁盘,进程重启不丢失)

适用场景:数据量大、跨进程共享、程序重启后仍需保留。

安装:

pip install diskcache
from diskcache import Cache
import time
# 创建一个磁盘缓存目录
cache = Cache("./my_cache_dir")
# 存入数据(可以设置过期时间)
cache.set("user_profile", {"name": "Alice", "age": 30}, expire=60*60)  # 1小时过期
# 获取数据
profile = cache.get("user_profile")
print(profile)  # 输出: {'name': 'Alice', 'age': 30}
# 即使程序重启,数据还在(只要不删除目录)
print(len(cache))  # 查看缓存条目数

高级用法:作为装饰器自动缓存函数结果

from diskcache import Cache
cache = Cache("./cache")
@cache.memoize(expire=600)  # 自动缓存函数返回值,10分钟过期
def fetch_weather(city):
    # 假设这里是一个HTTP请求
    time.sleep(3)
    return f"{city}的天气: 晴天"
print(fetch_weather("北京"))  # 第一次:慢
print(fetch_weather("北京"))  # 第二次:瞬间返回(缓存)

如何选择?

需求 推荐方案
临时小数据,代码简单 字典 + 手动管理
函数计算结果,少量参数 functools.lru_cache
需要TTL过期、多种淘汰策略 cachetools
数据量大、跨进程、需持久化 diskcache
读写频繁、高并发场景 考虑 RedisMemcached(本地缓存不够)

对于大多数 Python 应用场景,functools.lru_cache 是最简单高效的入门选择,而 cachetools 提供了更专业、更灵活的控制。

标签: ttl

抱歉,评论功能暂时关闭!