国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

如何使用Python內置緩存裝飾器: @lru_cache,@cache 與 @cached_property

這篇具有很好參考價值的文章主要介紹了如何使用Python內置緩存裝飾器: @lru_cache,@cache 與 @cached_property。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 為什么需要緩存技術?

使用緩存是優(yōu)化Python程序速度的重要方法之一。如果使用得當,可以大幅減少計算資源的負載,有效加快代碼運行速度

Python 的內置庫 functools 模塊附帶了@lru_cache,@cache, @cached_property 裝飾器,使用非常簡便,不需要安裝第3方庫,不需要 redis 等數(shù)據(jù)庫保存對象等,通常只需要1行代碼,就可以對函數(shù)運算結果、類成員方法運算結果進行緩存。

本文將介紹這3種緩存工具的使用步驟及實例。

2. @lru_cache 緩存裝飾器的使用

@lru_cache 是最常見的緩存裝飾器。lru_cache 是: Last recently used cache 的簡寫,可以將該函數(shù)最近調用的輸入?yún)?shù)以及結果進行緩存。如果有新的調用,先檢查緩存是否有相同的輸入?yún)?shù),如果存在,則直接返回對應結果。如果是無參函數(shù),第1次調用后,以后每次調用,直接返回緩存結果。

先看1個例子

from functools import lru_cache
from math import sin

@lru_cache
def sin_half(x):
    return sin(x)/2

print('first call result:',sin_half(60))
print('second call result:',sin_half(60))

上例中,第1次運行函數(shù)后,lru_cache會緩存調用參數(shù)及返回結果。第2次運行時,lru_cache都會檢查輸入,發(fā)現(xiàn)緩存中存在相同輸入?yún)?shù)60,則從緩存中返回結果。如果函數(shù)執(zhí)行的是計算量很重的任務,對于相同輸入,可以明顯地節(jié)省系統(tǒng)資源。

裝飾器參數(shù)

lru_cache默認不清除緩存內容,因此緩存會無限增長,如果程序是長期運行的服務,可能存在耗盡內存的風險。 因此,必須添加1個maxsize參數(shù):
@lru_cache(maxsize) 的參數(shù)maxsize 表示要緩存的最近調用次數(shù).
如 @lru_cache(360) 表示,只緩存最近360次的函數(shù)調用結果。

@lru_cache(360)
def sin_half(x):
    return sin(x)/2

緩存操作

查看緩存報告: sin_half.cache_info()
強制清除緩存內容: sin_half.cache_clear()
當然也可以使用 python的 garbage collection 清除緩存。

下面使用1個示例來演示上述內容:

import functools
import gc

# 主要功能: 
# 驗證  @lru_cache 裝飾器,.chche_info() 和 .cache_clear() 方法的使用
#       garbage collection 的使用

@functools.lru_cache(maxsize = 300) # Max number of Last recently used cache
def fib(n):
	if n < 2:
		return n
	return fib(n-1) + fib(n-2)


fib(30)
fib.cache_clear()

# Before Clearing
print(fib.cache_info())

# After Clearing
print(fib.cache_info())

@functools.lru_cache(maxsize = None)
def gfg1():
    # insert function logic here
    pass

# 再次運行函數(shù) 
gfg1()
fib(30)
# garbage collection
gc.collect()

# All objects collected
objects = [i for i in gc.get_objects() 
           if isinstance(i, functools._lru_cache_wrapper)]

print(gfg1.cache_info())

# All objects cleared
for object in objects:
    object.cache_clear()
    
print(gfg1.cache_info())

運行程度,輸出為:

CacheInfo(hits=0, misses=0, maxsize=300, currsize=0)
CacheInfo(hits=0, misses=0, maxsize=300, currsize=0)
CacheInfo(hits=0, misses=1, maxsize=None, currsize=1)
CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)

3. @cache 緩存裝飾器的使用

相比@lru_cache, @cache 裝飾器更輕量化,速度更快,且是線程安全,不同線程可以調用同1個函數(shù),緩存值可以共享。

import functools
import time

@functools.cache
def fib(n):
	if n < 2:
		return n
	return fib(n-1) + fib(n-2)
   
if __name__ == '__main__':
    
    start_time = time.time()
    print(fib(400))
    end_time = time.time()
    execution_time_without_cache = end_time - start_time
    print("Time taken without cache: {:.8f} seconds".format(execution_time_without_cache))
    
    start_time = time.time()
    print(fib(400))
    end_time = time.time()
    execution_time_without_cache = end_time - start_time
    print("Time taken with cache: {:.8f} seconds".format(execution_time_without_cache))    

output:

176023680645013966468226945392411250770384383304492191886725992896575345044216019675
Time taken without cache: 0.00095391 seconds
176023680645013966468226945392411250770384383304492191886725992896575345044216019675
Time taken with cache: 0.00000000 seconds

4. @cached_property 緩存裝飾器的使用

@cached_property是一個裝飾器,它將類的方法轉換為屬性,其值僅計算一次,然后緩存為普通屬性。因此,只要實例持久存在,緩存的結果就可用,我們可以將該方法用作類的屬性那樣來使用,如

調用:    : instance.method
取代舊方式 : instance.method()

@cached_property是 Python 中 functools 模塊的一部分。它類似于 property(),但 @cached_property 帶有一個額外的功能,那就是緩存。

但是它如何減少執(zhí)行時間并使程序更快?請考慮以下示例:

# Without using @cached_property

# A sample class
class Sample():

	def __init__(self, lst):
	self.long_list = lst

	# a method to find the sum of the
	# given long list of integer values
	def find_sum(self):
		return (sum(self.long_list))

# obj is an instance of the class sample
# the list can be longer, this is just
# an example
obj = Sample([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(obj.find_sum())
print(obj.find_sum())
print(obj.find_sum())

輸出為:

55
55
55

在這里,假設如果我們傳遞1個長列表,每次調用 find_sum()方法時都會計算給定列表的總和,從而花費大量時間運行,程序最終會變慢。我們想要的是,由于列表在創(chuàng)建實例后不會更改,因此,如果列表的總和只計算一次,而不是每次在我們調用方法并希望訪問總和時計算,那就太好了。這可以通過使用@cached_property來實現(xiàn),

# With using @cached_property

from functools import cached_property

# A sample class
class Sample():
	def __init__(self, lst):
	self.long_list = lst

	# a method to find the sum of the
	# given long list of integer values
	@cached_property
	def find_sum(self):
		return (sum(self.long_list))

# obj is an instance of the class sample
obj = Sample([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(obj.find_sum)
print(obj.find_sum)
print(obj.find_sum)

使用了@cached_property裝飾器后,無須重新計算,總是立即返回find_sum值。
如果需要重新計算屬性,則刪除該屬性即可,下次調用會重新計算,在本例 中添加如下語句,

del obj.find_sum
obj.long_list = range(20,30)
print(obj.find_sum)

運行代碼,輸出結果為:

55
55
55
245

5. 各種緩存方法的適用場景

綜上所述,建議如下:
1) 如果程序規(guī)模小,或多線程編程時,可使用@cache 裝飾器。
2) 如果程度規(guī)模大,并且是長時間運行,建議使用@lru_cache 裝飾器,使用方法靈活,但要注意控制緩存數(shù)量,必要時手工清理。
3) 編寫類代碼時,如需將某項復雜運算結果像屬性那樣訪問時,使用@cached_property裝飾器。文章來源地址http://www.zghlxwxcb.cn/news/detail-515076.html

到了這里,關于如何使用Python內置緩存裝飾器: @lru_cache,@cache 與 @cached_property的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • [力扣146. LRU 緩存 ](https://leetcode.cn/problems/lru-cache/description/)

    力扣146. LRU 緩存 使用LinkedHashmap(HashMap的子類,能夠記住插入數(shù)據(jù)的順序). LRU是Lease Recently User的縮寫,意思是最近 最少使用。比如設計一個文件緩存系統(tǒng),每個文件有自己的大小和訪問時間,文件緩存系統(tǒng)有總的大小,當往這個文件系統(tǒng)中放入新的文件時,如果發(fā)現(xiàn)超出文件

    2024年02月11日
    瀏覽(54)
  • 什么是瀏覽器緩存(browser caching)?如何使用HTTP頭來控制緩存?

    什么是瀏覽器緩存(browser caching)?如何使用HTTP頭來控制緩存?

    前端入門之旅:探索Web開發(fā)的奇妙世界 歡迎來到前端入門之旅!感興趣的可以訂閱本專欄哦!這個專欄是為那些對Web開發(fā)感興趣、剛剛踏入前端領域的朋友們量身打造的。無論你是完全的新手還是有一些基礎的開發(fā)者,這里都將為你提供一個系統(tǒng)而又親切的學習平臺。在這個

    2024年02月09日
    瀏覽(34)
  • LinkedHashMap如何實現(xiàn)LRU緩存淘汰策略?

    LinkedHashMap如何實現(xiàn)LRU緩存淘汰策略?

    LRU,Least Recently Used, 最近最少使用 ,也就是優(yōu)先淘汰最近最少使用的元素。 簡而言之,就是將LinedHashMap的accessOrder設為true即可。 demo實現(xiàn)如下: 測試一下: 3.1 LinkedHashMap簡介 LinkedHashMap內部維護了一個雙向鏈表,能保證元素按插入的順序訪問,也能以訪問順序訪問,可以用

    2023年04月24日
    瀏覽(39)
  • 愜意上手Python —— 裝飾器和內置函數(shù)

    愜意上手Python —— 裝飾器和內置函數(shù)

    ?Python中的裝飾器是一種特殊類型的函數(shù),它允許用戶在不修改原函數(shù)代碼的情況下,增加或修改函數(shù)的行為。 具體來說, 裝飾器的工作原理基于Python的函數(shù)也是對象這一事實,可以被賦值給變量、作為參數(shù)傳遞給其他函數(shù)或者作為其他函數(shù)的返回值。裝飾器通常接受一個函

    2024年01月24日
    瀏覽(19)
  • 系統(tǒng)學習Python——單元測試unittest:內置裝飾器

    分類目錄:《系統(tǒng)學習Python》總目錄 相關文章: · 單元測試unittest:框架結構 · 單元測試unittest:測試固件 · 單元測試unittest:編寫測試用例 · 單元測試unittest:執(zhí)行測試用例 · 單元測試unittest:用例執(zhí)行次序 · 單元測試unittest:內置裝飾器 · 單元測試unittest:命令行執(zhí)行測

    2023年04月13日
    瀏覽(93)
  • rust里如何快速實現(xiàn)一個LRU 本地緩存?

    LRU是Least Recently Used(最近最少使用)的縮寫,是一種常見的緩存淘汰算法。LRU算法的基本思想是,當緩存空間已滿時,優(yōu)先淘汰最近最少使用的數(shù)據(jù),以保留最常用的數(shù)據(jù)。 在計算機系統(tǒng)中,LRU算法常用于緩存系統(tǒng)、頁面置換算法等場景,以提高數(shù)據(jù)訪問的效率和性能。 要

    2024年02月13日
    瀏覽(28)
  • Python算法題集_LRU 緩存

    Python算法題集_LRU 緩存

    本文為Python算法題集之一的代碼示例 請你設計并實現(xiàn)一個滿足 LRU (最近最少使用) 緩存 約束的數(shù)據(jù)結構。 實現(xiàn) LRUCache 類: LRUCache(int capacity) 以 正整數(shù) 作為容量 capacity 初始化 LRU 緩存 int get(int key) 如果 key 存在于緩存中,則返回的值,否則返回 -1 。 void put(int

    2024年02月21日
    瀏覽(25)
  • python第6課(函數(shù),內置高階函數(shù),匿名函數(shù),裝飾器)筆記

    變量名的查找規(guī)則; 在訪問變量時,先查找本地變量,然后是包裹此函數(shù)的外部函數(shù)的內部變量,之后是全局變量,最后是內置變量 1 在函數(shù)內使用全局變量 2使用nonlocal聲明的變量不是局部變量,也不是全局變量,而是外部嵌套函數(shù)內的變量 函數(shù)名是變量,它在創(chuàng)建函數(shù)時綁

    2024年02月11日
    瀏覽(28)
  • 設計一個LRU(最近最少使用)緩存

    約束和假設 我們正在緩存什么? 我們正在緩存Web Query的結果 我們可以假設輸入是有效的,還是需要對其驗證? 假設輸入是有效的 我們可以假設它適應內存嗎? 對 編碼實現(xiàn)

    2024年01月24日
    瀏覽(107)
  • codeTop01:LRU (最近最少使用) 緩存的實現(xiàn)

    codeTop01:LRU (最近最少使用) 緩存的實現(xiàn)

    請你設計并實現(xiàn)一個滿足 LRU (最近最少使用) 緩存 約束的數(shù)據(jù)結構。 實現(xiàn) LRUCache 類: ● LRUCache(int capacity) 以 正整數(shù) 作為容量 capacity 初始化 LRU 緩存 ● int get(int key) 如果 key 存在于緩存中,則返回的值,否則返回 -1 。 ● void put(int key, int value) 如果 key 已

    2024年03月08日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包