利用Python編寫一個簡單的緩存系統(tǒng)
我們昨天已經學習了python
的文件讀寫,今天來做一個最簡單的例子,寫一個最簡單的緩存系統(tǒng),要求:
以key``value
的方式保持數據,并且需要將內容中的數據落地到文件,以便下次啟動的時候,將文件的內容加載進內存中來。
還是需要聲明一點,本篇文章所依賴的python
環(huán)境為:
代碼已經放到了gitee上,gitee
地址: gitee.com/pdudo/golearn/blob/master/python/cacheDB/main.py
項目展示
該demo
將分為2個部分展示,第一個部分我們會寫入一些key
和value
進入到緩存系統(tǒng)中,而后關閉程序。
第二部分則會去獲取第一個部分寫入的key
的名稱。
第一部分main
方法如下:
def main() -> None: c = dbCache("db.cache") c.cacheSetting(queueMaxKeys=3,ageSec=3) c.set("name","pdudo") c.set("site","juejin") c.set("hello","word") c.set("hello","pdudo")
其中,dbCache
是我們定義的類,而set
是寫入方法,cacheSetting
設置一些基礎環(huán)境變量,例如:
queueMaxKeys
: 需要制定增刪改緩存隊列,類型為int
,如果滿了,則立即落地到磁盤中。ageSec
: 間隔時間,參數為秒數,若操作第一個key
和操作第二個key
時間大于該設置,則落地到磁盤。
set
則是寫入方法,參數為key
和value
。
運行后,代碼效果如下:
由于我們只有set
,所以不會輸出任何信息,上述open file error
是正常的警告信息,不用管它。
第一部分操作完畢了,我們可以修改第二部分,使用get
去獲取第一次存儲的數據。
修改main
如下:
def main() -> None: c = dbCache("db.cache") c.cacheSetting(queueMaxKeys=3,ageSec=3) print(c.get("name")) print(c.get("hello")) print(c.get("site"))
運行后,效果如下:
由此可以驗證,從磁盤讀取文件并且加載進內存,沒什么問題。
除此之外,該庫還支持其他操作,例如:
# 定義一個緩存對象 c = dbCache("db.cache") # 配置環(huán)境變量 c.cacheSetting(queueMaxKeys=3,ageSec=3) # 寫 c.set("name","pdudo") # 讀 print(c.get("name")) # 修改 c.update("name", "juejin") # 刪除 c.delete("name")
接下來,我們就來看下,如何一步一步完成這個最簡單的緩存系統(tǒng)。
不用落地的緩存系統(tǒng)系統(tǒng)應該如何實現
在python
中,給我們提供了很多基礎的數據類型,例如 列表、字典等。所以說,就沒必要自己在定義一套屬于自己的數據類型了,可以直接使用現有的數據類型,例如本篇文章所使用的就是字典,這里簡單的鋪墊一下字典的增刪改查。
鋪墊python字典基本操作
定義一個空的字典a
,可以使用如下代碼:
a = {}
寫入key
可以直接使用a[key] = value
即可,例如:
a["name"] = "pdudo"
修改也是和上述一樣的
關于查詢,我們直接使用a[key]
即可。
若沒有這個key
會拋錯: KeyError: 'key'
。
print(a["name"])
檢查是否存在key
,可以使用key in dict
來判斷,例如: 想判斷name
是否是字典a
中的key
,可以寫為:
print("name" in a)
若存在于a
中,會返回True
,否則會返回False
。
定義一個不用落地的緩存系統(tǒng)
有了上述關于字典的基本操作,我們可以將其封裝一下,定義為自己的操作方法,例如:
class cacheDB(): def __init__(self): #定義空的字典 self.cache = {} #增 def set(self,key,value): self.cache[key] = value #查 def get(self,key): return self.cache[key] #修 def update(self,key,value): self.cache[key] = value #刪除 def delete(self,key): del self.cache[key] def main(): c = cacheDB() c. set("name","pdudo") print(c.get("name")) c.update("name","juejin") print(c.get("name")) c.delete("name") if __name__ == '__main__': main()
我們可以將上述方法,封裝在一個class
中,從而實現調用。
例如,運行之后結果為:
數據如何落地
上述,我們已經寫了一個最簡單的緩存系統(tǒng),如果此時進程掛掉了,重新啟動后,內存中的數據就都沒了,所以為了避免重啟后數據丟失,可以將數據定時落地到磁盤中,本篇文章所介紹的內置庫為: pickle
,該可可以將python
對象存儲到文件中,從而保存到磁盤,這個對象可以是字典、也可以是列表,我們來看下,具體方法:
將對象保存到磁盤
使用pickle
的dump
方法,可以將對象保持到文件中,這里舉一個很簡單的例子:
import pickle list1 = ["name","juejin","hello"] with open("test.txt","wb") as f: pickle.dump(list1,f)
上述代碼,先引入了pickle
庫,而后定義了列表list1
,最后打開文件,使用pickle.dump
將列表對象保持到文件中,這里保存的是二進制,所以是wb
模式。使用with...open
方法,它可以主動在最后幫我們關閉文件句柄。
此時如我們執(zhí)行腳本后,想查看一下文件,會發(fā)現是二進制格式的,例如:
將對象從磁盤中導入到內存中
上述,我們已經將對象保持到磁盤中,接下來,我們使用pickle
的load
方法,將磁盤數據導入到內存中來,這里同樣舉一個很簡答的例子:
import pickle with open("test.txt","rb") as f: list2 = pickle.load(f) print(list2)
上述代碼,還是先引入pickle
庫,而后在以二進制的模式讀取文件,最后通過pickle.load
方法,將數據從磁盤中導入到list2
下,接著輸出list2
的值。
運行后,可以發(fā)現,該值就是我們上述落地到磁盤的對象:
將數據落地和緩存系統(tǒng)結合起來
我們已經將數據落地測試完畢了,如何和緩存系統(tǒng)結合起來呢? 很簡單,我們僅需要在程序啟動時,檢測一下是否有該文件,若有,則直接讀取數據再并入到對象中,否則創(chuàng)建一個新的字典就好。
而后每次有增刪改操作,都將數據落地即可,這里用新增數據函數舉個例子:
class cacheDB(): def __init__(self): try: with open("db.cache","rb") as f: self.cache = pickle.load(f) except Exception as e: self.cache = {} def set(self,key,value): self.cache[key] = value with open("db.cache","wb") as f: pickle.dump(self.cache,f)
上述在cacheDB
的__init__
函數中,就嘗試讀取本地文件db.cache
,若存在,就load
到內存中,若不存在,就創(chuàng)建一個新的字典。
這樣的話,存儲的數據就不會因為程序重啟而丟失了。
如何保證并發(fā)安全
作為一個服務對開提供訪問時,需要注意一下并發(fā)安全,當多個函數對一個變量進行操作的時候,很容易引起數據混亂,所以還是有必要加一下鎖的,我們可以引入threading
庫來完成加鎖解鎖操作,其加鎖和解鎖代碼如下:
import threading lock = threading.Lock # 定義lock lock.acquire() # 加鎖 lock.release() # 釋放鎖
我們可以將次引入到代碼中,例如:
import pickle import threading lock = threading.lock class cacheDB(): def __init__(self): try: with open("db.cache","rb") as f: self.cache = pickle.load(f) except Exception as e: self.cache={} def set(self,key,value): lock.acquire() self.cache[key] = value with open("db.cache","wb") as f: pickle.dump(self.cache,f) lock.release() def main(): db = cacheDB() if __name__ == '__main__': main()
這里就不做演示了。
總結
本篇文章,介紹如何寫一個最簡單的緩存系統(tǒng),其核心點是定義了一個字典類型來保存key/value
數據,并且根據相應的邏輯,使用pickle
的load
方法保持到本地磁盤中,而后需要加載的時候再從本地文件加載到內容中即可,最后作為一個服務,應當考慮到并發(fā)安全的問題,給增刪改方法加一個鎖,從而避免并發(fā)問題。最后的最后,再將功能重復代碼給踢出來,稍微潤色一下,就差不多可以了。
到此這篇關于利用Python編寫一個簡單的緩存系統(tǒng)的文章就介紹到這了,更多相關Python緩存系統(tǒng)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python使用pyautogui模塊實現自動化鼠標和鍵盤操作示例
這篇文章主要介紹了Python使用pyautogui模塊實現自動化鼠標和鍵盤操作,簡單描述了pyautogui模塊的功能,并結合實例形式較為詳細的分析了Python使用pyautogui模塊實現鼠標與鍵盤自動化操作相關技巧,需要的朋友可以參考下2018-09-09python+selenium定時爬取丁香園的新型冠狀病毒數據并制作出類似的地圖(部署到云服務器)
這篇文章主要介紹了python+selenium定時爬取丁香園的新冠病毒每天的數據并制作出類似的地圖(部署到云服務器),本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02Python基于pygame實現單機版五子棋對戰(zhàn)
這篇文章主要為大家詳細介紹了Python基于pygame實現單機版五子棋對戰(zhàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-12-12