Python3 shelve對(duì)象持久存儲(chǔ)原理詳解
1.shelve對(duì)象的持久存儲(chǔ)
不需要關(guān)系數(shù)據(jù)庫(kù)時(shí),可以用shelve模塊作為持久存儲(chǔ)Python對(duì)象的一個(gè)簡(jiǎn)單的選擇。類似于字典,shelf按鍵訪問。值將被pickled并寫至由dbm創(chuàng)建和管理的數(shù)據(jù)庫(kù)。
1.1 創(chuàng)建一個(gè)新shelf
使用shelve最簡(jiǎn)單的方法就是利用DbfilenameShelf類。它使用dbm存儲(chǔ)數(shù)據(jù)。這個(gè)類可以直接使用,也可以通過調(diào)用shelve.open()來使用。
import shelve with shelve.open('test_shelf.db') as s: s['key1'] = { 'int': 10, 'float': 9.5, 'string': 'Sample data', }
再次訪問這個(gè)數(shù)據(jù),可以打開shelf,并像字典一樣使用它。
import shelve with shelve.open('test_shelf.db') as s: existing = s['key1'] print(existing)
運(yùn)行這兩個(gè)示例腳本會(huì)生成以下輸出。
dbm模塊不支持多個(gè)應(yīng)用同時(shí)寫同一個(gè)數(shù)據(jù)庫(kù),不過它支持并發(fā)的只讀客戶。如果一個(gè)客戶沒有修改shelf,則可以通過傳入flag='r'來告訴shelve以只讀方式打開數(shù)據(jù)庫(kù)。
import dbm import shelve with shelve.open('test_shelf.db', flag='r') as s: print('Existing:', s['key1']) try: s['key1'] = 'new value' except dbm.error as err: print('ERROR: {}'.format(err))
如果數(shù)據(jù)庫(kù)作為只讀數(shù)據(jù)源打開,并且程序試圖修改數(shù)據(jù)庫(kù),那么便會(huì)生成一個(gè)訪問錯(cuò)誤異常。具體的異常類型取決于創(chuàng)建數(shù)據(jù)庫(kù)時(shí)dbm選擇的數(shù)據(jù)庫(kù)模塊。
1.2 寫回
默認(rèn)的,shelf不會(huì)跟蹤對(duì)可變對(duì)象的修改。這說明,如果存儲(chǔ)在shelf中的一個(gè)元素的內(nèi)容有變化,那么shelf必須再次存儲(chǔ)整個(gè)元素來顯式的更新。
import shelve with shelve.open('test_shelf.db') as s: print(s['key1']) s['key1']['new_value'] = 'this was not here before' with shelve.open('test_shelf.db', writeback=True) as s: print(s['key1'])
在這個(gè)例子中,沒有再次存儲(chǔ)'key1'的相應(yīng)字典,所以重新打開shelf時(shí),修改不會(huì)保留。
對(duì)于shelf中存儲(chǔ)的可變對(duì)象,要想自動(dòng)捕獲對(duì)它們的修改,可以在打開shelf時(shí)啟用寫回(writeback)。writeback標(biāo)志會(huì)讓shelf使用內(nèi)存中緩存以記住從數(shù)據(jù)庫(kù)獲取的所有對(duì)象。shelf關(guān)閉時(shí)每個(gè)緩存對(duì)象也被寫回到數(shù)據(jù)庫(kù)。
import shelve import pprint with shelve.open('test_shelf.db', writeback=True) as s: print('Initial data:') pprint.pprint(s['key1']) s['key1']['new_value'] = 'this was not here before' print('\nModified:') pprint.pprint(s['key1']) with shelve.open('test_shelf.db', writeback=True) as s: print('\nPreserved:') pprint.pprint(s['key1'])
盡管這會(huì)減少程序員犯錯(cuò)的機(jī)會(huì),并且使對(duì)象持久存儲(chǔ)更透明,但是并非所有情況都有必要使用寫回模式。打開shelf時(shí)緩存會(huì)消耗額外的內(nèi)容,關(guān)閉shelf時(shí)會(huì)暫時(shí)將各個(gè)緩存對(duì)象寫回到數(shù)據(jù)庫(kù),這會(huì)減慢應(yīng)用的速度。所有緩存的對(duì)象都要寫回?cái)?shù)據(jù)庫(kù),因?yàn)闊o法區(qū)分它們是否有修改。如果應(yīng)用讀取的數(shù)據(jù)多于寫的數(shù)據(jù),那么寫回就會(huì)影響性能而沒有太大意義。
1.3 特定shelf類型
之前的例子都使用了默認(rèn)的shelf實(shí)現(xiàn)。可以使用shelve.open()而不是直接使用某個(gè)shelf實(shí)現(xiàn),這是一種常用的用法,特別是使用什么類型的數(shù)據(jù)庫(kù)來存儲(chǔ)數(shù)據(jù)并不重要時(shí)。不過,有些情況下數(shù)據(jù)庫(kù)格式會(huì)很重要。在這些情況下,可以直接使用DbfilenameShelf或BsdDbshelf,或者甚至可以派生Shelf來得到一個(gè)定制解決方案。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
對(duì)Python中range()函數(shù)和list的比較
下面小編就為大家分享一篇對(duì)Python中range()函數(shù)和list的比較,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04分享一下Python數(shù)據(jù)分析常用的8款工具
Python是數(shù)據(jù)處理常用工具,可以處理數(shù)量級(jí)從幾K至幾T不等的數(shù)據(jù),具有較高的開發(fā)效率和可維護(hù)性,還具有較強(qiáng)的通用性和跨平臺(tái)性,這里就為大家分享幾個(gè)不錯(cuò)的數(shù)據(jù)分析工具,需要的朋友可以參考下2018-04-04Python運(yùn)行報(bào)錯(cuò)UnicodeDecodeError的解決方法
本文給大家分享的是在Python項(xiàng)目中經(jīng)常遇到的關(guān)于編碼問題的一個(gè)小bug的解決方法以及分析方法,有相同遭遇的小伙伴可以來參考下2016-06-06Python數(shù)據(jù)結(jié)構(gòu)之列表與元組詳解
序列是Python中最基本的數(shù)據(jù)結(jié)構(gòu)。序列中的每個(gè)元素都分配一個(gè)數(shù)字 - 它的位置,或索引,第一個(gè)索引是0,第二個(gè)索引是1,依此類推,元組與列表類似,不同之處在于元組的元素不能修改。元組使用小括號(hào),列表使用方括號(hào)2021-10-10python刪除文件夾中具有相同后綴類型文件的實(shí)戰(zhàn)演練
在平時(shí)卸載軟件的時(shí)候會(huì)殘留許多文件和空文件夾,下面這篇文章主要給大家介紹了關(guān)于python刪除文件夾中具有相同后綴類型文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03Python獲取系統(tǒng)所有進(jìn)程PID及進(jìn)程名稱的方法示例
這篇文章主要介紹了Python獲取系統(tǒng)所有進(jìn)程PID及進(jìn)程名稱的方法,涉及Python使用psutil對(duì)系統(tǒng)進(jìn)程進(jìn)行操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-05-05python實(shí)現(xiàn)將html表格轉(zhuǎn)換成CSV文件的方法
這篇文章主要介紹了python實(shí)現(xiàn)將html表格轉(zhuǎn)換成CSV文件的方法,涉及Python操作csv文件的相關(guān)技巧,需要的朋友可以參考下2015-06-06如何使用python爬取知乎熱榜Top50數(shù)據(jù)
主要是爬取知乎熱榜的問題及點(diǎn)贊數(shù)比較高的答案,通過requests請(qǐng)求庫(kù)進(jìn)行爬取,對(duì)大家的學(xué)習(xí)或工作具有一定的價(jià)值,需要的朋友可以參考下2021-09-09