本文目录导读:

- 使用 functools.lru_cache(最简单的缓存装饰器)
- 使用 cachetools(更灵活的缓存库)
- 使用字典手动实现缓存
- 使用 file-based 缓存(文件缓存)
- 使用 redis 作为缓存(适合生产环境)
- 完整示例:带过期时间的缓存装饰器
- 选择建议
在Python中设置本地缓存有多种方式,我为你介绍几种常用的方法:
使用 functools.lru_cache(最简单的缓存装饰器)
from functools import lru_cache
@lru_cache(maxsize=128) # maxsize 缓存最大数量
def expensive_function(n):
"""模拟一个耗时计算"""
print(f"计算 {n}...")
return n * n
# 测试
print(expensive_function(5)) # 计算 5
print(expensive_function(5)) # 直接从缓存读取,不计算
print(expensive_function(10)) # 计算 10
print(expensive_function.cache_info()) # 查看缓存统计
使用 cachetools(更灵活的缓存库)
from cachetools import cached, TTLCache, LRUCache
import time
# 创建缓存:最大100个,过期时间30秒
cache = TTLCache(maxsize=100, ttl=30)
@cached(cache)
def get_data(url):
"""模拟获取网络数据"""
print(f"从 {url} 获取数据...")
return f"数据来自 {url}"
# 测试
print(get_data("https://api.example.com/data1")) # 第一次获取
print(get_data("https://api.example.com/data1")) # 从缓存读取
time.sleep(31)
print(get_data("https://api.example.com/data1")) # 缓存已过期,重新获取
使用字典手动实现缓存
class SimpleCache:
def __init__(self):
self.cache = {}
def get(self, key):
if key in self.cache:
return self.cache[key]
return None
def set(self, key, value):
self.cache[key] = value
def clear(self):
self.cache.clear()
# 使用示例
cache = SimpleCache()
def get_user_info(user_id):
# 先检查缓存
cached_data = cache.get(f"user_{user_id}")
if cached_data:
print(f"从缓存获取用户 {user_id} 信息")
return cached_data
# 模拟从数据库获取
print(f"从数据库获取用户 {user_id} 信息")
user_data = {"id": user_id, "name": f"用户{user_id}"}
# 存入缓存
cache.set(f"user_{user_id}", user_data)
return user_data
# 测试
print(get_user_info(1)) # 从数据库获取
print(get_user_info(1)) # 从缓存获取
使用 file-based 缓存(文件缓存)
import json
import os
import time
class FileCache:
def __init__(self, cache_dir="cache"):
self.cache_dir = cache_dir
os.makedirs(cache_dir, exist_ok=True)
def _get_cache_path(self, key):
# 使用 key 的哈希值作为文件名
filename = str(hash(key)) + ".json"
return os.path.join(self.cache_dir, filename)
def get(self, key):
cache_path = self._get_cache_path(key)
if not os.path.exists(cache_path):
return None
with open(cache_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# 检查是否过期(这里设置24小时过期)
if time.time() - data['timestamp'] > 86400:
os.remove(cache_path)
return None
return data['value']
def set(self, key, value):
cache_path = self._get_cache_path(key)
data = {
'key': key,
'value': value,
'timestamp': time.time()
}
with open(cache_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False)
# 使用示例
file_cache = FileCache()
# 保存缓存
file_cache.set("api_response", {"result": "success", "data": [1,2,3]})
# 读取缓存
result = file_cache.get("api_response")
print(result) # {'result': 'success', 'data': [1, 2, 3]}
使用 redis 作为缓存(适合生产环境)
# 首先安装 redis: pip install redis
import redis
import json
# 连接 Redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def get_data_with_redis(key, expiration=3600):
"""从 Redis 获取数据,过期时间 1小时"""
# 尝试从缓存获取
cached = redis_client.get(key)
if cached:
print(f"从 Redis 缓存获取 {key}")
return json.loads(cached.decode())
# 模拟获取数据
print(f"重新获取数据 {key}")
data = {"key": key, "value": "some data"}
# 存入 Redis
redis_client.setex(
key,
expiration,
json.dumps(data)
)
return data
# 测试
result = get_data_with_redis("user:1")
result = get_data_with_redis("user:1") # 第二次从缓存获取
完整示例:带过期时间的缓存装饰器
import time
from functools import wraps
def ttl_cache(seconds=60):
"""自定义TTL缓存装饰器"""
cache = {}
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 生成缓存key
key = str(args) + str(sorted(kwargs.items()))
# 检查缓存
if key in cache:
value, timestamp = cache[key]
if time.time() - timestamp < seconds:
print(f"缓存命中: {func.__name__}{args}")
return value
# 执行函数
result = func(*args, **kwargs)
# 更新缓存
cache[key] = (result, time.time())
print(f"更新缓存: {func.__name__}{args}")
return result
return wrapper
return decorator
# 使用自定义缓存
@ttl_cache(seconds=5)
def slow_function(n):
"""模拟耗时操作"""
time.sleep(2) # 模拟2秒的耗时
return n * 2
# 测试
print(slow_function(5)) # 等待2秒
print(slow_function(5)) # 立即返回(缓存命中)
time.sleep(6) # 等待缓存过期
print(slow_function(5)) # 重新计算,等待2秒
选择建议
- 简单场景:使用
functools.lru_cache - 需要过期时间:使用
cachetools.TTLCache - 需要持久化:使用文件缓存
- 分布式系统:使用 Redis
- 简单需求:手动实现字典缓存
根据你的具体需求选择合适的缓存方案!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播