最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中緩存入門實(shí)戰(zhàn)之核心概念與用法詳解

 更新時(shí)間:2026年01月09日 09:17:41   作者:愛吃提升  
緩存是提升程序性能的關(guān)鍵技術(shù),可以大幅的降低響應(yīng)時(shí)間,本文是Python 緩存的入門指南,涵蓋核心概念、常用實(shí)現(xiàn)方式和實(shí)戰(zhàn)案例,感興趣的小伙伴可以了解下

緩存是提升程序性能的關(guān)鍵技術(shù)——將頻繁訪問的「計(jì)算結(jié)果/數(shù)據(jù)」臨時(shí)存儲在高速介質(zhì)(如內(nèi)存)中,避免重復(fù)計(jì)算/重復(fù)查詢(如數(shù)據(jù)庫、API),從而大幅降低響應(yīng)時(shí)間。以下是 Python 緩存的入門指南,涵蓋核心概念、常用實(shí)現(xiàn)方式和實(shí)戰(zhàn)案例。

一、緩存的核心概念

1. 核心目標(biāo)

減少「高耗時(shí)操作」的執(zhí)行次數(shù)(如數(shù)據(jù)庫查詢、復(fù)雜計(jì)算、網(wǎng)絡(luò)請求),用空間換時(shí)間。

2. 關(guān)鍵術(shù)語

  • 緩存鍵(Key):唯一標(biāo)識緩存數(shù)據(jù)的索引(如函數(shù)參數(shù)、請求URL);
  • 緩存值(Value):存儲的目標(biāo)數(shù)據(jù)(如查詢結(jié)果、計(jì)算結(jié)果);
  • 過期時(shí)間(TTL):緩存數(shù)據(jù)的有效期,避免數(shù)據(jù)過期;
  • 緩存失效:緩存數(shù)據(jù)與源數(shù)據(jù)不一致(需設(shè)計(jì)失效策略,如過期、更新后主動(dòng)刪除);
  • 緩存命中率:命中緩存的請求數(shù) / 總請求數(shù)(越高性能越好)。

3. 適用場景

  • 頻繁調(diào)用的純函數(shù)(輸入固定則輸出固定);
  • 數(shù)據(jù)庫/Redis/API 等外部資源的重復(fù)查詢;
  • 復(fù)雜計(jì)算(如數(shù)據(jù)統(tǒng)計(jì)、機(jī)器學(xué)習(xí)模型推理);
  • Web 服務(wù)的接口響應(yīng)(如接口返回的靜態(tài)數(shù)據(jù))。

二、Python 緩存的常用實(shí)現(xiàn)方式

1. 方式1:手動(dòng)實(shí)現(xiàn)緩存(字典)

最簡單的緩存方式,用 Python 字典存儲鍵值對,適合小型腳本/簡單場景。

示例:緩存斐波那契數(shù)列計(jì)算(避免重復(fù)遞歸)

# 手動(dòng)緩存字典
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)  # 未命中,計(jì)算后存入緩存
    fib_cache[n] = result
    return result

# 測試:首次計(jì)算n=30(耗時(shí)),后續(xù)直接取緩存
print(fibonacci(30))  # 首次計(jì)算,存入緩存
print(fibonacci(30))  # 命中緩存,瞬間返回

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):極簡、無依賴、靈活;
  • 缺點(diǎn):無過期時(shí)間、線程不安全、內(nèi)存占用無限制(易內(nèi)存泄漏)、程序重啟后緩存丟失。

2. 方式2:functools.lru_cache(裝飾器,Python 內(nèi)置)

Python 標(biāo)準(zhǔn)庫 functools 提供的「最近最少使用(LRU)」緩存裝飾器,專為函數(shù)緩存設(shè)計(jì),自動(dòng)管理緩存生命周期。

基礎(chǔ)用法:緩存函數(shù)返回值

from functools import lru_cache

# @lru_cache 裝飾器:緩存函數(shù)調(diào)用結(jié)果
# maxsize:緩存最大條目數(shù)(None 表示無限制),typed=True 區(qū)分不同類型參數(shù)(如 1 和 1.0)
@lru_cache(maxsize=None, typed=False)
def calculate_square(x):
    print(f"計(jì)算 {x} 的平方(未命中緩存)")
    return x * x

# 測試
print(calculate_square(5))  # 未命中,執(zhí)行函數(shù)并緩存
print(calculate_square(5))  # 命中緩存,直接返回
print(calculate_square(10)) # 未命中,執(zhí)行并緩存

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

# 清空緩存
calculate_square.cache_clear()

進(jìn)階:緩存帶參數(shù)的數(shù)據(jù)庫查詢模擬

from functools import lru_cache

# 模擬數(shù)據(jù)庫查詢(高耗時(shí)操作)
def query_db(user_id):
    print(f"查詢數(shù)據(jù)庫:user_id={user_id}")
    return {"id": user_id, "name": f"User{user_id}", "age": 20 + user_id}

# 緩存查詢結(jié)果(注意:裝飾器僅緩存可哈希參數(shù),列表/字典需轉(zhuǎn)為元組/凍結(jié)集合)
@lru_cache(maxsize=100)
def get_user(user_id):
    return query_db(user_id)

# 測試
print(get_user(1))  # 未命中,查詢數(shù)據(jù)庫
print(get_user(1))  # 命中緩存,直接返回
print(get_user(2))  # 未命中,查詢數(shù)據(jù)庫

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):內(nèi)置無需安裝、自動(dòng)管理緩存(LRU 淘汰策略)、支持緩存清空/信息查看;
  • 缺點(diǎn):無過期時(shí)間、僅支持函數(shù)緩存、程序重啟后緩存丟失、不支持分布式(僅進(jìn)程內(nèi))。

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

cachetools 是 Python 第三方緩存庫,擴(kuò)展了 lru_cache 的能力,支持 TTL(過期時(shí)間)、LFU(最少使用)、FIFO(先進(jìn)先出)等策略。

步驟1:安裝

pip install cachetools

步驟2:實(shí)戰(zhàn):帶過期時(shí)間的緩存

from cachetools import TTLCache, cached

# 定義緩存規(guī)則:最大容量100,過期時(shí)間10秒(TTL)
cache = TTLCache(maxsize=100, ttl=10)

# 裝飾器綁定緩存規(guī)則
@cached(cache)
def get_weather(city):
    # 模擬調(diào)用天氣API(高耗時(shí))
    print(f"調(diào)用天氣API:{city}")
    return {"city": city, "temperature": 25, "time": "2025-11-25"}

# 測試
print(get_weather("北京"))  # 未命中,調(diào)用API
print(get_weather("北京"))  # 命中緩存(10秒內(nèi))
# 10秒后再次調(diào)用:緩存過期,重新調(diào)用API

支持的緩存策略

策略說明適用場景
TTLCache帶過期時(shí)間的LRU需定期更新數(shù)據(jù)(如天氣)
LRUCache最近最少使用淘汰通用場景
LFUCache最少使用淘汰訪問頻率不均的場景
FIFOCache先進(jìn)先出淘汰順序訪問的場景

4. 方式4:分布式緩存(Redis)—— 跨進(jìn)程/跨機(jī)器共享

以上方式均為「進(jìn)程內(nèi)緩存」(僅當(dāng)前程序可用),若需多進(jìn)程/多機(jī)器共享緩存,需用 Redis(高性能鍵值數(shù)據(jù)庫)。

步驟1:安裝依賴

# 安裝redis驅(qū)動(dòng)
pip install redis

步驟2:啟動(dòng)Redis(本地/遠(yuǎn)程)

  • 本地安裝
  • 測試可用:redis-cli ping → 返回 PONG。

步驟3:Python 操作 Redis 緩存

import redis
import time

# 連接Redis(本地默認(rèn)端口6379,無密碼)
r = redis.Redis(
    host="localhost",
    port=6379,
    password="",  # 若有密碼請?zhí)顚?
    db=0,         # 選擇數(shù)據(jù)庫0
    decode_responses=True  # 自動(dòng)將字節(jié)轉(zhuǎn)為字符串
)

# 封裝緩存函數(shù)
def get_data_from_cache(key, ttl=60):
    """從Redis獲取緩存,無則返回None"""
    return r.get(key)

def set_data_to_cache(key, value, ttl=60):
    """存入Redis緩存,設(shè)置過期時(shí)間(秒)"""
    r.setex(key, ttl, value)

# 模擬業(yè)務(wù)函數(shù):查詢用戶信息
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
    # 緩存未命中,查詢數(shù)據(jù)庫(模擬)
    print(f"查詢數(shù)據(jù)庫:{cache_key}")
    db_data = f"User {user_id} Info"
    # 存入緩存,過期時(shí)間60秒
    set_data_to_cache(cache_key, db_data, ttl=60)
    return db_data

# 測試
print(get_user_info(1001))  # 未命中,查數(shù)據(jù)庫并緩存
print(get_user_info(1001))  # 命中緩存
time.sleep(61)  # 等待緩存過期
print(get_user_info(1001))  # 緩存過期,重新查詢

優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):分布式共享、支持過期時(shí)間、持久化、高可用;
  • 缺點(diǎn):需部署Redis服務(wù)、有網(wǎng)絡(luò)開銷、增加系統(tǒng)復(fù)雜度。

三、緩存的最佳實(shí)踐

1. 選擇合適的緩存粒度

  • 細(xì)粒度:緩存單個(gè)數(shù)據(jù)(如單個(gè)用戶信息),命中率高,失效影響??;
  • 粗粒度:緩存聚合數(shù)據(jù)(如所有用戶列表),命中率低,失效影響大。

2. 設(shè)置合理的過期時(shí)間

  • 靜態(tài)數(shù)據(jù)(如省份列表):過期時(shí)間設(shè)為幾小時(shí)/幾天;
  • 動(dòng)態(tài)數(shù)據(jù)(如用戶余額):過期時(shí)間設(shè)為幾秒/幾分鐘;
  • 實(shí)時(shí)性要求高的數(shù)據(jù)(如秒殺庫存):盡量不緩存,或緩存時(shí)間極短。

3. 避免緩存穿透

問題:查詢不存在的數(shù)據(jù)(如 user_id=-1),緩存永遠(yuǎn)不命中,導(dǎo)致每次都查數(shù)據(jù)庫,壓垮數(shù)據(jù)庫。

解決方案:緩存空值(如 r.setex("user:-1", 60, "null")),并設(shè)置短過期時(shí)間。

4. 避免緩存雪崩

問題:大量緩存同時(shí)過期,導(dǎo)致大量請求直接打向數(shù)據(jù)庫。

解決方案

  • 過期時(shí)間加隨機(jī)值(如 ttl=60 + random.randint(0, 10));
  • 分布式緩存集群(如Redis集群);
  • 數(shù)據(jù)庫加限流/熔斷(如 ratelimit 庫)。

5. 緩存更新策略

  • 寫穿(Write-Through):更新數(shù)據(jù)庫后立即更新緩存;
  • 寫回(Write-Back):先更新緩存,異步更新數(shù)據(jù)庫(適合高并發(fā)寫);
  • 失效優(yōu)先:更新數(shù)據(jù)庫后刪除緩存,下次查詢時(shí)重新加載(最簡單)。

四、緩存庫選型建議

場景推薦方案
簡單函數(shù)緩存(單進(jìn)程)functools.lru_cache
帶過期時(shí)間的函數(shù)緩存cachetools.TTLCache
分布式/跨進(jìn)程緩存Redis + redis 庫
Web 框架集成(如Flask)flask-caching(封裝Redis/內(nèi)存)
高性能本地緩存pylibmc(基于memcached)

五、總結(jié)

Python 緩存入門的核心是:

  • 優(yōu)先用內(nèi)置工具(lru_cache)解決簡單場景;
  • 需過期時(shí)間用 cachetools;
  • 分布式場景用 Redis;
  • 設(shè)計(jì)緩存時(shí)必須考慮「過期時(shí)間」「失效策略」「命中率」,避免緩存穿透/雪崩。

緩存是性能優(yōu)化的「第一選擇」,但不要過度設(shè)計(jì)——先通過性能測試找到瓶頸,再針對性加緩存,而非盲目為所有函數(shù)加緩存。

到此這篇關(guān)于Python中緩存入門實(shí)戰(zhàn)之核心概念與用法詳解的文章就介紹到這了,更多相關(guān)Python緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python裝飾器decorator實(shí)際應(yīng)用與高級使用詳解

    Python裝飾器decorator實(shí)際應(yīng)用與高級使用詳解

    本文系統(tǒng)講解Python裝飾器,強(qiáng)調(diào)其作為函數(shù)包裝工具的核心作用,通過不修改原函數(shù)代碼實(shí)現(xiàn)功能擴(kuò)展,適用于日志、計(jì)時(shí)、認(rèn)證等場景,利用函數(shù)一等公民特性提升代碼復(fù)用性與可維護(hù)性
    2025-07-07
  • python基礎(chǔ)教程之popen函數(shù)操作其它程序的輸入和輸出示例

    python基礎(chǔ)教程之popen函數(shù)操作其它程序的輸入和輸出示例

    popen函數(shù)允許一個(gè)程序?qū)⒘硪粋€(gè)程序作為新進(jìn)程啟動(dòng),并可以傳遞數(shù)據(jù)給它或者通過它接收數(shù)據(jù),下面使用示例學(xué)習(xí)一下他的使用方法
    2014-02-02
  • Python讀取CSV文件的四種方法總結(jié)

    Python讀取CSV文件的四種方法總結(jié)

    這篇文章主要介紹了Python讀取CSV文件的四種方法, 使用 csv 模塊,使用 numpy 庫,使用pandas庫,使用標(biāo)準(zhǔn)庫中的 csv 模塊這四種方法,文章通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Python正則表達(dá)式?r'(.*)?are?(.*?)?.*'的深入理解

    Python正則表達(dá)式?r'(.*)?are?(.*?)?.*'的深入理解

    日常的開發(fā)工作中經(jīng)常會有處理字符串的需求,簡單的字符串處理,我們使用python內(nèi)置的字符串處理函數(shù)就可以了,但是復(fù)雜的字符串匹配就需要借助正則表達(dá)式了,這篇文章主要給大家介紹了關(guān)于Python正則表達(dá)式?r‘(.*)?are?(.*?)?.*‘的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • 對比Python中__getattr__和 __getattribute__獲取屬性的用法

    對比Python中__getattr__和 __getattribute__獲取屬性的用法

    這篇文章主要介紹了對比Python中__getattr__和 __getattribute__獲取屬性的用法,注意二者間的區(qū)別,__getattr__只作用于不存在的屬性,需要的朋友可以參考下
    2016-06-06
  • matplotlib之Pyplot模塊繪制三維散點(diǎn)圖使用顏色表示數(shù)值大小

    matplotlib之Pyplot模塊繪制三維散點(diǎn)圖使用顏色表示數(shù)值大小

    在撰寫論文時(shí)常常會用到matplotlib來繪制三維散點(diǎn)圖,下面這篇文章主要給大家介紹了關(guān)于matplotlib之Pyplot模塊繪制三維散點(diǎn)圖使用顏色表示數(shù)值大小的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Python 錯(cuò)誤和異常小結(jié)

    Python 錯(cuò)誤和異常小結(jié)

    這不是一篇關(guān)于Python異常的全面介紹的文章,這只是在學(xué)習(xí)Python異常后的一篇筆記式的記錄和小結(jié)性質(zhì)的文章
    2013-10-10
  • 使用urllib庫的urlretrieve()方法下載網(wǎng)絡(luò)文件到本地的方法

    使用urllib庫的urlretrieve()方法下載網(wǎng)絡(luò)文件到本地的方法

    今天小編就為大家分享一篇使用urllib庫的urlretrieve()方法下載網(wǎng)絡(luò)文件到本地的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • pytorch模型轉(zhuǎn)換為onnx可視化(使用netron)

    pytorch模型轉(zhuǎn)換為onnx可視化(使用netron)

    netron 是一個(gè)非常好用的網(wǎng)絡(luò)結(jié)構(gòu)可視化工具,但是netron對pytorch模型的支持還不成熟,這篇文章主要介紹了pytorch模型轉(zhuǎn)換為onnx,并使用netron可視化,需要的朋友可以參考下
    2023-05-05
  • keras中模型訓(xùn)練class_weight,sample_weight區(qū)別說明

    keras中模型訓(xùn)練class_weight,sample_weight區(qū)別說明

    這篇文章主要介紹了keras中模型訓(xùn)練class_weight,sample_weight區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05

最新評論

察雅县| 玛曲县| 永平县| 庄河市| 阳城县| 汕头市| 正阳县| 福海县| 宁德市| 景宁| 弋阳县| 湘西| 云霄县| 江北区| 时尚| 龙泉市| 紫金县| 庄浪县| 庆阳市| 平利县| 依兰县| 衡水市| 左权县| 鄂尔多斯市| 东港市| 定兴县| 于田县| 贵定县| 志丹县| 南木林县| 榆社县| 商南县| 九龙坡区| 巴南区| 龙泉市| 松桃| 宣汉县| 吉安市| 陵川县| 南华县| 安阳县|