如何在 Python 中實現持久對象
在編程中,常常需要將數據保存在磁盤上,以便下次程序運行時提取數據并使用。愛掏網 - it200.com這就需要使用持久對象,即可以在多次程序執行之間保持狀態的對象。愛掏網 - it200.comPython 為我們提供了多種方式來實現持久對象,本文就介紹其中的兩種:pickle 和 shelve。愛掏網 - it200.com
pickle 是 Python 標準庫中的一個模塊,它可以將 Python 對象序列化成字節流,以便可以將其寫入磁盤或發送到網絡。愛掏網 - it200.com反之,也可以將字節流反序列化成 Python 對象。愛掏網 - it200.compickle 不僅支持所謂的“普通”對象(數字、字符串、列表等),而且還可以對自定義類進行序列化和反序列化。愛掏網 - it200.com
序列化
讓我們來看一個小例子,假設我們有一個名為 Person 的類,其中有兩個屬性:姓名和年齡:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
我們創建一個 Person 對象并對其進行序列化:
import pickle
person = Person('Tom', 20)
with open('person.pkl', 'wb') as f:
pickle.dump(person, f)
這樣,我們就將 person 對象序列化到了一個名為 person.pkl 的文件中。愛掏網 - it200.com下面我們來看看 person.pkl 文件:
這看起來不是很直觀,事實上,pickle 默認是將對象以二進制格式存儲到文件中的。愛掏網 - it200.com如果我們想要將這些內容以字符串形式顯示,可以使用 pickle.dumps()
方法:
import pickle
person = Person('Tom', 20)
person_str = pickle.dumps(person)
print(person_str)
輸出:
b'\x80\x04\x95?\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x06Person\x94\x93\x94\x8c\x04name\x94\x8c\x03Tom\x94\x8c\x03age\x94K\x14\x86\x94.'
反序列化
我們現在有一個名為 person.pkl 的文件,想要將其反序列化為 Python 對象,可以使用 pickle.load()
方法:
import pickle
with open('person.pkl', 'rb') as f:
person = pickle.load(f)
print(person.name, person.age)
輸出:
Tom 20
注意事項
pickle 在序列化 Python 對象時有一些限制。愛掏網 - it200.com以下是一些最常見的:
- 無法序列化 lambda、函數和方法。愛掏網 - it200.com
- 無法序列化實例方法(由于它們包含對實例的引用)。愛掏網 - it200.com
- 無法在不同計算機之間共享 pickle(因為 pickle 包含了 Python 對象的完整表示,而不是二進制數據)。愛掏網 - it200.com
- 序列化和反序列化都需要使用相同的 pickle 版本(否則可能會出現錯誤或不兼容性)。愛掏網 - it200.com
- pickle 可能存在安全風險(例如,當加載 pickle 文件時,如果不信任文件源,則 pickle 可能會執行惡意代碼)。愛掏網 - it200.com
Shelve
shelve 模塊是 Python 標準庫中的一個鍵值存儲模塊,顧名思義,它的作用類似于書架:將一系列“書籍”存儲在其中,并通過“書名”來查找和獲取它們。愛掏網 - it200.comshelve 可以存儲 Python 對象,并將其序列化為字節流,以便可以將其寫入磁盤或發送到網絡。愛掏網 - it200.com與 pickle 不同,shelve 存儲的是一個個對象,而不是一個個字節流。愛掏網 - it200.com
存儲
讓我們來看一個小例子,假設我們有一個名為 Person 的類(與 pickle 中的相同),我們可以使用 shelve 存儲多個 Person 對象:
import shelve
with shelve.open('persons') as db:
db['person1'] = Person('Tom', 20)
db['person2'] = Person('Jerry', 30)
這里我們使用了 shelve.open()
方法來打開一個名為 persons 的數據庫,并使用 db['person1']
和 db['person2']
來存儲兩個 Person 對象。愛掏網 - it200.com保存在磁盤上的數據類似于一個字典,每一個鍵值對就是一個對象。愛掏網 - it200.com
獲取
我們現在已經將多個 Person 對象存儲在了數據庫中,我們可以通過鍵名來獲取它們:
import shelve
with shelve.open('persons') as db:
person1 = db['person1']
person2 = db['person2']
print(person1.name, person1.age)
print(person2.name, person2.age)
輸出: