python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python缓存

Python中缓存入门实战之核心概念与用法详解

作者:爱吃提升

缓存是提升程序性能的关键技术,可以大幅的降低响应时间,本文是Python 缓存的入门指南,涵盖核心概念、常用实现方式和实战案例,感兴趣的小伙伴可以了解下

缓存是提升程序性能的关键技术——将频繁访问的「计算结果/数据」临时存储在高速介质(如内存)中,避免重复计算/重复查询(如数据库、API),从而大幅降低响应时间。以下是 Python 缓存的入门指南,涵盖核心概念、常用实现方式和实战案例。

一、缓存的核心概念

1. 核心目标

减少「高耗时操作」的执行次数(如数据库查询、复杂计算、网络请求),用空间换时间。

2. 关键术语

3. 适用场景

二、Python 缓存的常用实现方式

1. 方式1:手动实现缓存(字典)

最简单的缓存方式,用 Python 字典存储键值对,适合小型脚本/简单场景。

示例:缓存斐波那契数列计算(避免重复递归)

# 手动缓存字典
fib_cache = {}

def fibonacci(n):
    if n in fib_cache:  # 命中缓存,直接返回
        return fib_cache[n]
    if n <= 1:
        result = n
    else:
        result = fibonacci(n-1) + fibonacci(n-2)  # 未命中,计算后存入缓存
    fib_cache[n] = result
    return result

# 测试:首次计算n=30(耗时),后续直接取缓存
print(fibonacci(30))  # 首次计算,存入缓存
print(fibonacci(30))  # 命中缓存,瞬间返回

优缺点

2. 方式2:functools.lru_cache(装饰器,Python 内置)

Python 标准库 functools 提供的「最近最少使用(LRU)」缓存装饰器,专为函数缓存设计,自动管理缓存生命周期。

基础用法:缓存函数返回值

from functools import lru_cache

# @lru_cache 装饰器:缓存函数调用结果
# maxsize:缓存最大条目数(None 表示无限制),typed=True 区分不同类型参数(如 1 和 1.0)
@lru_cache(maxsize=None, typed=False)
def calculate_square(x):
    print(f"计算 {x} 的平方(未命中缓存)")
    return x * x

# 测试
print(calculate_square(5))  # 未命中,执行函数并缓存
print(calculate_square(5))  # 命中缓存,直接返回
print(calculate_square(10)) # 未命中,执行并缓存

# 查看缓存信息
print(calculate_square.cache_info())  # CacheInfo(hits=1, misses=2, maxsize=None, currsize=2)

# 清空缓存
calculate_square.cache_clear()

进阶:缓存带参数的数据库查询模拟

from functools import lru_cache

# 模拟数据库查询(高耗时操作)
def query_db(user_id):
    print(f"查询数据库:user_id={user_id}")
    return {"id": user_id, "name": f"User{user_id}", "age": 20 + user_id}

# 缓存查询结果(注意:装饰器仅缓存可哈希参数,列表/字典需转为元组/冻结集合)
@lru_cache(maxsize=100)
def get_user(user_id):
    return query_db(user_id)

# 测试
print(get_user(1))  # 未命中,查询数据库
print(get_user(1))  # 命中缓存,直接返回
print(get_user(2))  # 未命中,查询数据库

优缺点

3. 方式3:第三方库(cachetools)—— 支持更多缓存策略

cachetools 是 Python 第三方缓存库,扩展了 lru_cache 的能力,支持 TTL(过期时间)、LFU(最少使用)、FIFO(先进先出)等策略。

步骤1:安装

pip install cachetools

步骤2:实战:带过期时间的缓存

from cachetools import TTLCache, cached

# 定义缓存规则:最大容量100,过期时间10秒(TTL)
cache = TTLCache(maxsize=100, ttl=10)

# 装饰器绑定缓存规则
@cached(cache)
def get_weather(city):
    # 模拟调用天气API(高耗时)
    print(f"调用天气API:{city}")
    return {"city": city, "temperature": 25, "time": "2025-11-25"}

# 测试
print(get_weather("北京"))  # 未命中,调用API
print(get_weather("北京"))  # 命中缓存(10秒内)
# 10秒后再次调用:缓存过期,重新调用API

支持的缓存策略

策略说明适用场景
TTLCache带过期时间的LRU需定期更新数据(如天气)
LRUCache最近最少使用淘汰通用场景
LFUCache最少使用淘汰访问频率不均的场景
FIFOCache先进先出淘汰顺序访问的场景

4. 方式4:分布式缓存(Redis)—— 跨进程/跨机器共享

以上方式均为「进程内缓存」(仅当前程序可用),若需多进程/多机器共享缓存,需用 Redis(高性能键值数据库)。

步骤1:安装依赖

# 安装redis驱动
pip install redis

步骤2:启动Redis(本地/远程)

步骤3:Python 操作 Redis 缓存

import redis
import time

# 连接Redis(本地默认端口6379,无密码)
r = redis.Redis(
    host="localhost",
    port=6379,
    password="",  # 若有密码请填写
    db=0,         # 选择数据库0
    decode_responses=True  # 自动将字节转为字符串
)

# 封装缓存函数
def get_data_from_cache(key, ttl=60):
    """从Redis获取缓存,无则返回None"""
    return r.get(key)

def set_data_to_cache(key, value, ttl=60):
    """存入Redis缓存,设置过期时间(秒)"""
    r.setex(key, ttl, value)

# 模拟业务函数:查询用户信息
def get_user_info(user_id):
    # 先查缓存
    cache_key = f"user:{user_id}"
    cache_data = get_data_from_cache(cache_key)
    if cache_data:
        print(f"命中缓存:{cache_key}")
        return cache_data
    # 缓存未命中,查询数据库(模拟)
    print(f"查询数据库:{cache_key}")
    db_data = f"User {user_id} Info"
    # 存入缓存,过期时间60秒
    set_data_to_cache(cache_key, db_data, ttl=60)
    return db_data

# 测试
print(get_user_info(1001))  # 未命中,查数据库并缓存
print(get_user_info(1001))  # 命中缓存
time.sleep(61)  # 等待缓存过期
print(get_user_info(1001))  # 缓存过期,重新查询

优缺点

三、缓存的最佳实践

1. 选择合适的缓存粒度

2. 设置合理的过期时间

3. 避免缓存穿透

问题:查询不存在的数据(如 user_id=-1),缓存永远不命中,导致每次都查数据库,压垮数据库。

解决方案:缓存空值(如 r.setex("user:-1", 60, "null")),并设置短过期时间。

4. 避免缓存雪崩

问题:大量缓存同时过期,导致大量请求直接打向数据库。

解决方案

5. 缓存更新策略

四、缓存库选型建议

场景推荐方案
简单函数缓存(单进程)functools.lru_cache
带过期时间的函数缓存cachetools.TTLCache
分布式/跨进程缓存Redis + redis 库
Web 框架集成(如Flask)flask-caching(封装Redis/内存)
高性能本地缓存pylibmc(基于memcached)

五、总结

Python 缓存入门的核心是:

缓存是性能优化的「第一选择」,但不要过度设计——先通过性能测试找到瓶颈,再针对性加缓存,而非盲目为所有函数加缓存。

到此这篇关于Python中缓存入门实战之核心概念与用法详解的文章就介绍到这了,更多相关Python缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文