您好,登錄后才能下訂單哦!
1.shelve對象的持久存儲
不需要關(guān)系數(shù)據(jù)庫時,可以用shelve模塊作為持久存儲Python對象的一個簡單的選擇。類似于字典,shelf按鍵訪問。值將被pickled并寫至由dbm創(chuàng)建和管理的數(shù)據(jù)庫。
1.1 創(chuàng)建一個新shelf
使用shelve最簡單的方法就是利用DbfilenameShelf類。它使用dbm存儲數(shù)據(jù)。這個類可以直接使用,也可以通過調(diào)用shelve.open()來使用。
import shelve with shelve.open('test_shelf.db') as s: s['key1'] = { 'int': 10, 'float': 9.5, 'string': 'Sample data', }
再次訪問這個數(shù)據(jù),可以打開shelf,并像字典一樣使用它。
import shelve with shelve.open('test_shelf.db') as s: existing = s['key1'] print(existing)
運行這兩個示例腳本會生成以下輸出。
dbm模塊不支持多個應(yīng)用同時寫同一個數(shù)據(jù)庫,不過它支持并發(fā)的只讀客戶。如果一個客戶沒有修改shelf,則可以通過傳入flag='r'來告訴shelve以只讀方式打開數(shù)據(jù)庫。
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ù)庫作為只讀數(shù)據(jù)源打開,并且程序試圖修改數(shù)據(jù)庫,那么便會生成一個訪問錯誤異常。具體的異常類型取決于創(chuàng)建數(shù)據(jù)庫時dbm選擇的數(shù)據(jù)庫模塊。
1.2 寫回
默認的,shelf不會跟蹤對可變對象的修改。這說明,如果存儲在shelf中的一個元素的內(nèi)容有變化,那么shelf必須再次存儲整個元素來顯式的更新。
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'])
在這個例子中,沒有再次存儲'key1'的相應(yīng)字典,所以重新打開shelf時,修改不會保留。
對于shelf中存儲的可變對象,要想自動捕獲對它們的修改,可以在打開shelf時啟用寫回(writeback)。writeback標志會讓shelf使用內(nèi)存中緩存以記住從數(shù)據(jù)庫獲取的所有對象。shelf關(guān)閉時每個緩存對象也被寫回到數(shù)據(jù)庫。
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'])
盡管這會減少程序員犯錯的機會,并且使對象持久存儲更透明,但是并非所有情況都有必要使用寫回模式。打開shelf時緩存會消耗額外的內(nèi)容,關(guān)閉shelf時會暫時將各個緩存對象寫回到數(shù)據(jù)庫,這會減慢應(yīng)用的速度。所有緩存的對象都要寫回數(shù)據(jù)庫,因為無法區(qū)分它們是否有修改。如果應(yīng)用讀取的數(shù)據(jù)多于寫的數(shù)據(jù),那么寫回就會影響性能而沒有太大意義。
1.3 特定shelf類型
之前的例子都使用了默認的shelf實現(xiàn)??梢允褂胹helve.open()而不是直接使用某個shelf實現(xiàn),這是一種常用的用法,特別是使用什么類型的數(shù)據(jù)庫來存儲數(shù)據(jù)并不重要時。不過,有些情況下數(shù)據(jù)庫格式會很重要。在這些情況下,可以直接使用DbfilenameShelf或BsdDbshelf,或者甚至可以派生Shelf來得到一個定制解決方案。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。