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

Python?cachetools實(shí)現(xiàn)緩存過(guò)期策略

 更新時(shí)間:2025年06月27日 08:57:57   作者:程序員小jobleap  
cachetools?是一個(gè)功能強(qiáng)大的?Python?庫(kù),用于實(shí)現(xiàn)多種緩存策略,幫助開(kāi)發(fā)者優(yōu)化程序性能,下面小編就來(lái)和大家詳細(xì)講講cachetools的原理與應(yīng)用吧

cachetools 是一個(gè)功能強(qiáng)大的 Python 庫(kù),用于實(shí)現(xiàn)多種緩存策略(如 LRU、TTL、LFU 等),幫助開(kāi)發(fā)者優(yōu)化程序性能。無(wú)論是頻繁調(diào)用高開(kāi)銷(xiāo)函數(shù),還是減少重復(fù)計(jì)算,cachetools 都能顯著提升效率。以下是詳細(xì)的基礎(chǔ)知識(shí)點(diǎn)講解及豐富的代碼案例。

安裝與配置

在開(kāi)始使用 cachetools 之前,需要通過(guò) pip 安裝:

pip install cachetools

安裝完成后,即可直接使用,無(wú)需復(fù)雜配置。

核心概念與用法

1. 緩存類(lèi)型介紹

  • LRUCache(Least Recently Used) :最近最少使用緩存,會(huì)優(yōu)先移除最久未被訪問(wèn)的項(xiàng)目。
  • TTLCache(Time-To-Live) :設(shè)置緩存項(xiàng)的存活時(shí)間,過(guò)期后自動(dòng)刪除。
  • LFUCache(Least Frequently Used) :最少頻繁使用緩存,會(huì)移除訪問(wèn)頻率最低的項(xiàng)目。

2. 創(chuàng)建緩存對(duì)象

以下是創(chuàng)建不同類(lèi)型緩存的示例:

from cachetools import LRUCache, TTLCache, LFUCache

# 創(chuàng)建 LRU 緩存,最大容量為 5
lru_cache = LRUCache(maxsize=5)

# 創(chuàng)建 TTL 緩存,最大容量為 10,每項(xiàng)存活時(shí)間為 60 秒
ttl_cache = TTLCache(maxsize=10, ttl=60)

# 創(chuàng)建 LFU 緩存,最大容量為 3
lfu_cache = LFUCache(maxsize=3)

3. 函數(shù)結(jié)果緩存

通過(guò)裝飾器將函數(shù)結(jié)果緩存起來(lái),避免重復(fù)計(jì)算:

from cachetools import cached, TTLCache

# 創(chuàng)建一個(gè) TTL 緩存
cache = TTLCache(maxsize=3, ttl=10)

@cached(cache)
def expensive_computation(x):
    print(f"Computing {x}...")
    return x * x

# 第一次調(diào)用會(huì)計(jì)算并緩存
print(expensive_computation(4))  # 輸出: 16
# 第二次調(diào)用直接從緩存獲取
print(expensive_computation(4))  # 輸出: 16(無(wú)計(jì)算)

注意:當(dāng)緩存項(xiàng)過(guò)期或超出容量時(shí),將觸發(fā)重新計(jì)算。

4. LRU 緩存示例

LRU 緩存會(huì)自動(dòng)移除最近最少使用的項(xiàng)目:

from cachetools import LRUCache

cache = LRUCache(maxsize=2)

# 添加數(shù)據(jù)到緩存中
cache['a'] = 1
cache['b'] = 2

print(cache)  # 輸出: {'a': 1, 'b': 2}

# 添加新數(shù)據(jù),超出容量時(shí)移除最少使用的數(shù)據(jù)
cache['c'] = 3
print(cache)  # 輸出: {'b': 2, 'c': 3}

5. 自定義鍵生成函數(shù)

可以通過(guò)自定義鍵函數(shù)處理復(fù)雜參數(shù),如忽略某些參數(shù)或處理不可哈希對(duì)象:

from cachetools import cached, LRUCache, keys

def custom_key(*args, **kwargs):
    return keys.hashkey(*args) + tuple(sorted(kwargs.items()))

cache = LRUCache(maxsize=128)

@cached(cache, key=custom_key)
def fetch_data(x, y, z=None):
    print(f"Fetching data for {x}, {y}, {z}")
    return x + y + (z or 0)

print(fetch_data(1, 2, z=3))  # 實(shí)際調(diào)用
print(fetch_data(1, 2, z=3))  # 從緩存中獲取

6. 完整案例:API 數(shù)據(jù)緩存

以下示例展示如何利用 TTLCache 緩存 API 請(qǐng)求結(jié)果,避免重復(fù)網(wǎng)絡(luò)請(qǐng)求:

import requests
from cachetools import cached, TTLCache

# 創(chuàng)建一個(gè) TTL 緩存,最大容量為 5,每項(xiàng)生存時(shí)間為 30 秒
api_cache = TTLCache(maxsize=5, ttl=30)

@cached(api_cache)
def fetch_api_data(url):
    print(f"Fetching data from {url}")
    response = requests.get(url)
    return response.json() if response.status_code == 200 else None

url = "https://jsonplaceholder.typicode.com/todos/1"
print(fetch_api_data(url))   # 實(shí)際請(qǐng)求 API
print(fetch_api_data(url))   # 從緩存獲取結(jié)果

性能測(cè)試與優(yōu)化效果

以下是 cachetools 在實(shí)際應(yīng)用中的性能提升效果:

場(chǎng)景無(wú)緩存耗時(shí)使用 cachetools 耗時(shí)提升比例
Fibonacci 數(shù)列計(jì)算~2 秒~0.01 秒~200 倍
API 數(shù)據(jù)請(qǐng)求(10 次相同)~10 秒~1 秒~10 倍

通過(guò)減少重復(fù)計(jì)算和網(wǎng)絡(luò)請(qǐng)求,cachetools 可顯著節(jié)省資源。

Python cachetools 實(shí)現(xiàn)緩存過(guò)期策略

實(shí)現(xiàn)代碼

from cachetools import TTLCache
import time
 
class CallbackTTLCache(TTLCache):
    """支持過(guò)期回調(diào)的 TTL 緩存"""
    def __init__(self, maxsize, ttl, callback=None):
        super().__init__(maxsize, ttl)
        self.callback = callback  # 過(guò)期回調(diào)函數(shù)
        self._pending_callbacks = {}  # 跟蹤需要回調(diào)的項(xiàng)目
 
    def __setitem__(self, key, value, **kwargs):
        super().__setitem__(key, value, **kwargs)
        if self.callback:
            self._pending_callbacks[key] = value
 
    def __getitem__(self, key):
        try:
            return super().__getitem__(key)
        except KeyError:
            if key in self._pending_callbacks:
                value = self._pending_callbacks.pop(key)
                if self.callback:
                    self.callback(key, value)
            raise
 
    def popitem(self):
        """淘汰條目時(shí)觸發(fā)回調(diào)"""
        try:
            key, value = super().popitem()
            if key in self._pending_callbacks:
                self._pending_callbacks.pop(key)
            if self.callback:
                self.callback(key, value)
            return key, value
        except KeyError:
            print("緩存已經(jīng)為空")
            return None, None
 
    def clear_expired(self):
        """清理所有過(guò)期的項(xiàng)目并觸發(fā)回調(diào)"""
        current_time = time.time()
        expired_keys = []
        
        # 檢查所有鍵是否過(guò)期
        for key in list(self._pending_callbacks):
            try:
                # 嘗試獲取值,如果過(guò)期會(huì)拋出KeyError
                _ = self[key]
            except KeyError:
                # 如果拋出KeyError,說(shuō)明已過(guò)期
                expired_keys.append(key)
        
        # 觸發(fā)過(guò)期回調(diào)
        for key in expired_keys:
            if key in self._pending_callbacks:
                value = self._pending_callbacks.pop(key)
                if self.callback:
                    self.callback(key, value)
 
    def clear(self):
        """清空緩存并觸發(fā)所有回調(diào)"""
        for key, value in list(self._pending_callbacks.items()):
            if self.callback:
                self.callback(key, value)
        self._pending_callbacks.clear()
        super().clear()
 
# 示例:定義過(guò)期回調(diào)函數(shù)
def on_expired(key, value):
    print(f"?? 緩存過(guò)期!Key: {key}, Value: {value} 已清除")
 
# 初始化緩存(最大100條,有效期5秒,綁定回調(diào))
cache = CallbackTTLCache(maxsize=100, ttl=5, callback=on_expired)
 
# 測(cè)試用例
def run_tests():
    print("=== 開(kāi)始測(cè)試 ===")
    
    # 測(cè)試1:添加并立即訪問(wèn)緩存
    print("\n測(cè)試1:添加并立即訪問(wèn)緩存")
    cache["user_101"] = "Alice"
    cache["user_102"] = "Bob"
    print("初始緩存內(nèi)容:", dict(cache.items()))
    
    # 測(cè)試2:等待部分時(shí)間后訪問(wèn)
    print("\n測(cè)試2:等待3秒后訪問(wèn)緩存")
    time.sleep(3)
    print("訪問(wèn)user_101:", cache.get("user_101", "已過(guò)期"))
    print("3秒后緩存內(nèi)容:", dict(cache.items()))
    
    # 測(cè)試3:等待過(guò)期并嘗試訪問(wèn)
    print("\n測(cè)試3:等待剩余時(shí)間直到過(guò)期")
    time.sleep(3)  # 再等3秒,總共6秒,確保過(guò)期
    print("嘗試訪問(wèn)user_101:", cache.get("user_101", "已過(guò)期"))
    print("6秒后(過(guò)期)緩存內(nèi)容:", dict(cache.items()))
    
    # 測(cè)試4:手動(dòng)清理過(guò)期內(nèi)容
    print("\n測(cè)試4:清理過(guò)期內(nèi)容")
    cache.clear_expired()
    print("清理后緩存內(nèi)容:", dict(cache.items()))
    
    # 測(cè)試5:嘗試對(duì)空緩存調(diào)用popitem
    print("\n測(cè)試5:對(duì)空緩存調(diào)用popitem")
    key, value = cache.popitem()
    print(f"popitem結(jié)果 - Key: {key}, Value: {value}")
    
    print("\n=== 測(cè)試完成 ===")
 
if __name__ == "__main__":
    run_tests()
import time
from functools import wraps
 
def timed_cache(ttl=60, callback=None):
    """支持過(guò)期時(shí)間和回調(diào)的緩存裝飾器"""
    cache = {}
    
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            key = (args, frozenset(kwargs.items()))
            current_time = time.time()
            
            # 檢查緩存是否命中且未過(guò)期
            if key in cache:
                result, expire_time = cache[key]
                if current_time < expire_time:
                    return result
                elif callback:  # 觸發(fā)過(guò)期回調(diào)
                    callback(key, result)
            
            # 重新計(jì)算并緩存結(jié)果
            result = func(*args, **kwargs)
            cache[key] = (result, current_time + ttl)
            return result
        return wrapper
    return decorator
 
# 定義回調(diào)函數(shù)
def expire_callback(key, value):
    print(f"?? 回調(diào)通知: 參數(shù) {key} 的值 {value} 已過(guò)期")
 
# 應(yīng)用裝飾器
@timed_cache(ttl=3, callback=expire_callback)
def heavy_compute(x):
    print(f"計(jì)算中... 參數(shù)={x}")
    return x ** 2
 
# 測(cè)試
print(heavy_compute(4))  # 首次計(jì)算,輸出: 計(jì)算中... 16
print(heavy_compute(4))  # 命中緩存,無(wú)輸出 → 16
time.sleep(4)
print(heavy_compute(4))  # 過(guò)期后重新計(jì)算,觸發(fā)回調(diào) → 計(jì)算中... 16

總結(jié)與建議

  • cachetools 提供了多種靈活的緩存策略(如 LRU、TTL、LFU 等),適用于不同場(chǎng)景。
  • 使用簡(jiǎn)單,可通過(guò)裝飾器快速實(shí)現(xiàn)函數(shù)結(jié)果緩存。
  • 在實(shí)際開(kāi)發(fā)中,應(yīng)根據(jù)需求選擇合適的緩存類(lèi)型和參數(shù)配置。

推薦在 Web 開(kāi)發(fā)、機(jī)器學(xué)習(xí)、大數(shù)據(jù)處理等需要高效數(shù)據(jù)訪問(wèn)的場(chǎng)景中使用 cachetools。

到此這篇關(guān)于Python cachetools實(shí)現(xiàn)緩存過(guò)期策略的文章就介紹到這了,更多相關(guān)Python cachetools緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python hashlib模塊實(shí)例使用詳解

    Python hashlib模塊實(shí)例使用詳解

    這篇文章主要介紹了Python hashlib模塊實(shí)例使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • python添加菜單圖文講解

    python添加菜單圖文講解

    在本篇文章中小編給大家整理的是關(guān)于python添加菜單圖文講解以及步驟分析,需要的朋友們學(xué)習(xí)下吧。
    2019-06-06
  • python之DataFrame實(shí)現(xiàn)excel合并單元格

    python之DataFrame實(shí)現(xiàn)excel合并單元格

    這篇文章主要為大家詳細(xì)介紹了python之DataFrame實(shí)現(xiàn)excel合并單元格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Python中g(shù)event模塊協(xié)程使用

    Python中g(shù)event模塊協(xié)程使用

    協(xié)程是一種用戶態(tài)的輕量級(jí)線程,本文主要介紹了Python中g(shù)event模塊協(xié)程使用,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • python中不同數(shù)據(jù)對(duì)象的空值校驗(yàn)總結(jié)

    python中不同數(shù)據(jù)對(duì)象的空值校驗(yàn)總結(jié)

    在Python中,我們可以使用不同的方式來(lái)校驗(yàn)數(shù)值的空值、字符串的空值以及對(duì)象的空值,本文為大家整理了一些常見(jiàn)的方法,希望對(duì)大家有所幫助
    2024-01-01
  • 如何將python項(xiàng)目部署在一臺(tái)服務(wù)器上

    如何將python項(xiàng)目部署在一臺(tái)服務(wù)器上

    服務(wù)器less技術(shù)是一種無(wú)需管理服務(wù)器即可運(yùn)行應(yīng)用程序的方法,最流行的服務(wù)器less平臺(tái)是AWS Lambda,這篇文章主要介紹了如何將python項(xiàng)目部署在一臺(tái)服務(wù)器上,需要的朋友可以參考下
    2023-10-10
  • python面試題小結(jié)附答案實(shí)例代碼

    python面試題小結(jié)附答案實(shí)例代碼

    這篇文章主要介紹了python面試題小結(jié),本文通過(guò)實(shí)例代碼相結(jié)合的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • pytest中的fixture基本用法

    pytest中的fixture基本用法

    fixture是pytest特有的功能,用以在測(cè)試執(zhí)行前和執(zhí)行后進(jìn)行必要的準(zhǔn)備和清理工作,這篇文章主要介紹了pytest中的fixture基本用法,需要的朋友可以參考下
    2023-02-02
  • 深度解析Python魔法函數(shù)中__getattr__與__getattribute__的核心奧義

    深度解析Python魔法函數(shù)中__getattr__與__getattribute__的核心奧義

    Python作為一門(mén)極具靈活性的動(dòng)態(tài)類(lèi)型語(yǔ)言,其驚艷的動(dòng)態(tài)特性并非憑空而來(lái),魔法函數(shù)正是支撐這一特性的底層靈魂,下面小編就和大家詳細(xì)介紹一下_getattr__與__getattribute__的調(diào)用機(jī)制,核心區(qū)別與實(shí)戰(zhàn)應(yīng)用吧
    2026-03-03
  • 利用Python批量循環(huán)讀取Excel的技巧分享

    利用Python批量循環(huán)讀取Excel的技巧分享

    這篇文章主要為大家詳細(xì)介紹了何用Python批量循環(huán)讀取Excel,文中的示例代碼講解詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的可以了解一下
    2023-07-07

最新評(píng)論

鹰潭市| 开平市| 灵石县| 延津县| 铁力市| 安远县| 云霄县| 新民市| 诏安县| 德惠市| 汽车| 永泰县| 古丈县| 策勒县| 乡宁县| 平利县| 五原县| 宝鸡市| 汉阴县| 广元市| 阳原县| 沙坪坝区| 清徐县| 大竹县| 额济纳旗| 临江市| 承德市| 来凤县| 潢川县| 同德县| 化州市| 固原市| 卢氏县| 大石桥市| 南溪县| 大连市| 霞浦县| 台南市| 延庆县| 龙口市| 建宁县|