能夠進行持久化的包有dbm和shelve,前者有一定限制,就是鍵值必須爲字符串或者字節,如果值爲列表或者字典再或者其他類型對象就會報錯,而後者的值可以爲任意python對象,這個特性依賴另一個包:pickle。pickle是將一個用來對象序列化、反序列化的包,關於pickle可以參考這個回答:
Python中 pickle有什麼意義,pickle了再恢復? - 劉奕聰的回答 - 知乎
https://www.zhihu.com/question/38355589/answer/89134351
來看一個shelve的例子
import shelve
def test_shelve():
# open 返回一個Shelf類的實例
#
# 參數flag的取值範圍:
# 'r':只讀打開
# 'w':讀寫訪問
# 'c':讀寫訪問,如果不存在則創建
# 'n':讀寫訪問,總是創建新的、空的數據庫文件
#
# protocol:與pickle庫一致
# writeback:爲True時,當數據發生變化會回寫,不過會導致內存開銷比較大
d = shelve.open('shelve.db', flag='c', protocol=2, writeback=False)
assert isinstance(d, shelve.Shelf)
# 在數據庫中插入一條記錄
d['abc'] = {'name': ['a', 'b']}
d.sync()
print(d['abc'])
# writeback是False,因此對value進行修改是不起作用的
d['abc']['x'] = 'x'
print(d['abc']) # 還是打印 {'name': ['a', 'b']}
# 當然,直接替換key的value還是起作用的
d['abc'] = 'xxx'
print(d['abc'])
# 還原abc的內容,爲下面的測試代碼做準備
d['abc'] = {'name': ['a', 'b']}
d.close()
# writeback 爲 True 時,對字段內容的修改會writeback到數據庫中。
d = shelve.open('shelve.db', writeback=True)
# 上面我們已經保存了abc的內容爲{'name': ['a', 'b']},打印一下看看對不對
print(d['abc'])
# 修改abc的value的部分內容
d['abc']['xx'] = 'xxx'
print(d['abc'])
d.close()
# 重新打開數據庫,看看abc的內容是否正確writeback
d = shelve.open('shelve.db')
print(d['abc'])
d.close()