@cache 是 Python 3.9+ 中引入的一个装饰器,用于自动缓存函数的结果,基于函数的参数。它是 @lru_cache(maxsize=None) 的简化版本。
原理
@cache 的核心原理是 记忆化(Memoization):
- 参数作为键:将函数的参数转换为哈希键
- 结果缓存:将函数返回值存储在与参数键对应的缓存中
- 命中返回:当相同参数再次出现时,直接返回缓存结果,避免重复计算
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13
| from functools import cache
@cache def fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
print(fibonacci(10))
|
与 @lru_cache 的比较
1 2 3 4 5 6 7 8 9 10
| from functools import cache, lru_cache
@cache def func1(x): return x * x
@lru_cache(maxsize=None) def func2(x): return x * x
|
实际应用示例
1. 计算密集型函数
1 2 3 4 5 6 7
| @cache def expensive_calculation(x, y): print(f"Computing {x} + {y}...") return x ** 2 + y ** 2
print(expensive_calculation(3, 4)) print(expensive_calculation(3, 4))
|
2. API 调用缓存
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import requests from functools import cache
@cache def get_user_data(user_id): print(f"Fetching data for user {user_id}") return {"user_id": user_id, "name": f"User {user_id}"}
user1 = get_user_data(1)
user1_cached = get_user_data(1)
|
3. 配置读取
1 2 3 4 5 6 7 8
| @cache def load_config(config_path): print(f"Loading config from {config_path}") return {"path": config_path, "settings": "some_settings"}
config1 = load_config("/etc/app/config.json") config2 = load_config("/etc/app/config.json")
|
注意事项
1. 参数必须可哈希
1 2 3 4 5 6 7 8 9 10
| @cache def process_data(data_list): return sum(data_list)
@cache def process_data(*args): return sum(args)
print(process_data(1, 2, 3))
|
2. 副作用函数不适合缓存
1 2 3 4 5 6 7 8 9 10 11
| counter = 0
@cache def increment_counter(): global counter counter += 1 return counter
print(increment_counter()) print(increment_counter())
|
3. 需要清除缓存的情况
1 2 3 4 5 6 7 8 9
| @cache def cached_function(x): return x * 2
cached_function.cache_clear()
print(cached_function.cache_info())
|
性能对比
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| from functools import cache import time
def fibonacci_naive(n): if n < 2: return n return fibonacci_naive(n-1) + fibonacci_naive(n-2)
@cache def fibonacci_cached(n): if n < 2: return n return fibonacci_cached(n-1) + fibonacci_cached(n-2)
start = time.time() result1 = fibonacci_naive(30) time1 = time.time() - start
start = time.time() result2 = fibonacci_cached(30) time2 = time.time() - start
print(f"无缓存: {time1:.4f}秒") print(f"有缓存: {time2:.4f}秒") print(f"加速比: {time1/time2:.1f}倍")
|
总结
@cache 装饰器适用于:
- 计算密集型函数
- 重复调用相同参数的函数
- IO 操作(如 API 调用、文件读取)
- 配置加载等初始化操作
不适用于:
- 有副作用的函数
- 参数不可哈希的情况
- 需要频繁更新结果的场景
使用 @cache 可以显著提升程序性能,但需要注意内存使用和缓存一致性。