cachetools,這是一個(gè)可擴(kuò)展的基于內(nèi)存的 Collections、Decorators 的封裝實(shí)現(xiàn)。
因?yàn)槭?Cache,那么就一定有它的頁(yè)面置換算法。根據(jù)操作系統(tǒng)學(xué)過(guò)的一些知識(shí),置換算法就會(huì)有 LRU、LFU、FIFO 等等。比如說(shuō),當(dāng) Cache 已經(jīng)滿(mǎn)了的情況下,如果這時(shí)候再插入一個(gè)新的數(shù)據(jù),那么這時(shí)候就需要根據(jù)頁(yè)面置換算法對(duì)已有的數(shù)據(jù)進(jìn)行置換,用新的數(shù)據(jù)替代舊的數(shù)據(jù),保證 Cache 最大占用量不會(huì)超標(biāo)。
廢話(huà)不多說(shuō)了,這里我們來(lái)體驗(yàn)下這個(gè)庫(kù)的具體用法吧。
首先是安裝,直接使用 pip3 安裝即可:
pip3 install cachetools
安裝好之后,我們?cè)賮?lái)看看它的具體用法。
基本 Cache 的使用
我們來(lái)看一個(gè)簡(jiǎn)單的實(shí)例:
from cachetools import Cache
cache = Cache(maxsize=3)
cache['1'] = 'Hello'
cache['2'] = 'World'
print('current size', cache.currsize)
cache.pop('2')
print(cache.items)
print('length', len(cache))
cache['3'] = 'Hello'
cache['4'] = 'World'
print('current size', cache.currsize)
cache['5'] = 'Hello'
print('current size', cache.currsize)
print(cache.items)
運(yùn)行結(jié)果如下:
current size 2
bound method Mapping.items of Cache([('1', 'Hello')], maxsize=3, currsize=1) >
length 1
current size 3
current size 3
bound method Mapping.items of Cache([('3', 'Hello'), ('4', 'World'), ('5', 'Hello')], maxsize=3, currsize=3) >
首先這里聲明了一個(gè) Cache 對(duì)象,有一個(gè)必傳的參數(shù)是 maxsize,這里設(shè)置為 3,這里的 3 其實(shí)就是長(zhǎng)度的意思,并不是實(shí)際內(nèi)存占用大小。
接著我們賦值了 1 和 2 兩個(gè)鍵名,接著打印出來(lái)了當(dāng)前 Cache 的大小,所以結(jié)果就是 2,這個(gè) size 就是一個(gè)單純的數(shù)量值。
然后接著調(diào)用了 pop 方法移除了 2 對(duì)應(yīng)的內(nèi)容,然后打印 Cache 的所有內(nèi)容和對(duì)應(yīng)長(zhǎng)度,理所應(yīng)當(dāng),長(zhǎng)度就是 2,然后就剩下一個(gè)值。
接著我們又賦值了 3 和 4 兩個(gè)鍵名,然后打印了當(dāng)前 Cache 的大小,這會(huì) Cache 達(dá)到了 maxsize,結(jié)果就是 3。
最后我們又賦值了 5 這個(gè)鍵名,然后打印了當(dāng)前 Cache 的大小和 Cache 的所有內(nèi)容,因?yàn)?Cache 已經(jīng)達(dá)到了 maxsize 了,所以結(jié)果依然是 3,最前面的 1 這個(gè)鍵名對(duì)應(yīng)的內(nèi)容就被移除了。
所以,這個(gè) Cache 對(duì)象可以維持一個(gè)最大恒定大小,并且保證長(zhǎng)度不會(huì)超過(guò) maxsize。
其他 Cache 的使用
當(dāng)然除了 Cache,還有一些 Cache 的子類(lèi),比如說(shuō) FIFOCache、LFUCahce、LRUCache、MRUCache、RRCache,這里簡(jiǎn)單說(shuō)下:
- FIFO:First In、First Out,就是先進(jìn)先出。
- LFU:Least Frequently Used,就是淘汰最不常用的。
- LRU:Least Recently Used,就是淘汰最久不用的。
- MRU:Most Recently Used,與 LRU 相反,淘汰最近用的。
- RR:Random Replacement,就是隨機(jī)替換。
具體的實(shí)例這里就不再講解了。
特殊 TTLCache 的使用
當(dāng)然除了基本的 Cache,cachetools 還提供了一種特殊的 Cache 實(shí)現(xiàn),叫做 TTLCache。
TTL 就是 time-to-live 的簡(jiǎn)稱(chēng),也就是說(shuō),Cache 中的每個(gè)元素都是有過(guò)期時(shí)間的,如果超過(guò)了這個(gè)時(shí)間,那這個(gè)元素就會(huì)被自動(dòng)銷(xiāo)毀。如果都沒(méi)過(guò)期并且 Cache 已經(jīng)滿(mǎn)了的話(huà),那就會(huì)采用 LRU 置換算法來(lái)替換掉最久不用的,以此來(lái)保證數(shù)量。
下面我們來(lái)看一個(gè)樣例:
from datetime import timedelta, datetime
from cachetools import TTLCache
from time import sleep
cache = TTLCache(maxsize=3, ttl=timedelta(seconds=5), timer=datetime.now)
cache['1'] = 'Hello'
sleep(1)
cache['2'] = 'World'
print(cache.items)
sleep(4.5)
print(cache.items)
sleep(1)
print(cache.items)
運(yùn)行結(jié)果如下:
這里我們聲明了一個(gè) TTLCache,maxsize 是 3,然后 ttl 設(shè)置為了 5 秒,也就是說(shuō),每個(gè)元素 5 秒之后都會(huì)過(guò)期。
首先我們賦值 1 這個(gè)鍵名為 Hello,然后 1 秒之后賦值 2 這個(gè)鍵名為 World,接著將現(xiàn)有 Cache 的結(jié)果輸出出來(lái)。
接著等待 4.5 秒,這時(shí)候 1 這個(gè)鍵名就已經(jīng)超過(guò) 5 秒了,所以 1 這個(gè)鍵名理應(yīng)就被銷(xiāo)毀了。
接著再等待 1 秒,這時(shí)候 2 這個(gè)鍵名也超過(guò) 5 秒了,所以 2 這個(gè)鍵名也理應(yīng)就被銷(xiāo)毀了。
最后看運(yùn)行結(jié)果也如我們期望的一樣。
大小計(jì)算
有的同學(xué)說(shuō),你這里 maxsize 用的這個(gè)數(shù)字指的是內(nèi)容的長(zhǎng)度,但實(shí)際上不同的內(nèi)容占用的空間是完全不一樣的,有沒(méi)有根據(jù)實(shí)際內(nèi)存占用來(lái)計(jì)算 size 的方法呢?
有的!
這里我們只需要替換掉 Cache 的 getsizeof 方法即可。
這里我們需要額外引入一個(gè)庫(kù),叫做 pympler,它提供了一個(gè) asizeof 方法可以計(jì)算實(shí)際 Object 的占用內(nèi)存大小,單位是 bytes。
pympler 安裝:
pip3 install pympler
所以,如果我們要設(shè)置 Cache 占用的最大內(nèi)存大小,比如 2MB,那就可以這么設(shè)置:
from cachetools import Cache
from pympler import asizeof
cache = Cache(maxsize=2 * 1024 * 1024, getsizeof=asizeof.asizeof)
cache['a'] = '123'
print(cache.currsize)
cache['b'] = '123'
print(cache.currsize)
cache['c'] = '456'
print(cache.currsize)
cache['d'] = {
'a': 'b',
'b': 'c',
'c': 'd'
}
print(cache.currsize)
這里 maxsize 我們就設(shè)置為了 2MB,同時(shí) getsizeof 方法設(shè)置為了 pympler 的 asizeof 方法,這樣 Cache 在計(jì)算 size 的時(shí)候就會(huì)用 asizeof 方法了。
這里我們隨便插入一些數(shù)據(jù),看看實(shí)際的 size 變化,運(yùn)行結(jié)果如下:
56
112
168
640
其結(jié)果就是 Cache 占用的字節(jié)數(shù)??梢钥吹綌?shù)據(jù)的復(fù)雜度高,占用的空間越大。
更多
好了,其實(shí)到現(xiàn)在為止,基本的 Cache 和 TTLCache 就夠我們使用了。
-
封裝
+關(guān)注
關(guān)注
128文章
8694瀏覽量
145565 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3125瀏覽量
75297 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7154瀏覽量
125648 -
Cache
+關(guān)注
關(guān)注
0文章
130瀏覽量
29093 -
python
+關(guān)注
關(guān)注
56文章
4827瀏覽量
86830
發(fā)布評(píng)論請(qǐng)先 登錄
labview中怎么實(shí)現(xiàn)類(lèi)似PPT中的超鏈接功能啊?
5種Python實(shí)現(xiàn)方式詳解
請(qǐng)問(wèn)Python中如何實(shí)現(xiàn)vlookup函數(shù)的功能?
Python解釋器的基本結(jié)構(gòu)
Cache中Tag電路的設(shè)計(jì)
Python語(yǔ)言在人工智能中的功能及優(yōu)勢(shì)
cache結(jié)構(gòu)與工作原理

jsonpath庫(kù)中的常規(guī)功能介紹

Buffer與cache的區(qū)別
抽樣在Python中是如何實(shí)現(xiàn)的
如何用Python來(lái)實(shí)現(xiàn)文件系統(tǒng)的操作功能

Cache內(nèi)容鎖定是什么
怎么在Python中實(shí)現(xiàn)截圖功能

C++中實(shí)現(xiàn)類(lèi)似instanceof的方法

評(píng)論