9.1 了解 pickle
模組 pickle 可以把幾乎所有的 Python 物件保存到文件或字串中,然後再把它恢復到原狀。pickle 支援許多數據類型,包括 自定義類的物件,並自動化將物件轉換為位元格式和返回的過程。
pickle 模組的主要功能
- 從文件中讀取和寫入物件
-
pickle.dump(obj, file): 序列化物件obj並將其寫入 已打開的文件file。 -
pickle.load(file): 從文件file讀取並反序列化物件。
-
- 從位元數組中讀取和寫入物件
-
pickle.dumps(obj): 序列化物件obj並將其作為 位元物件返回。 -
pickle.loads(bytes): 從位元物件中反序列化物件。
-
下面我們會更詳細地講解這些方法:
9.2 序列化到文件
文件序列化的基本步驟:
- 以位元寫入模式打開文件
(wb)。 - 使用
pickle.dump(obj, file)序列化物件。 - 使用
pickle.load(file)反序列化物件。 - 關閉文件。
將物件序列化和反序列化到文件
其實 pickle 無所謂序列化什麼。比如這樣 序列化一個列表:
import pickle
data = [1, 2, 3, 4, 5]
# 將列表序列化到文件
with open('list.pkl', 'wb') as file:
pickle.dump(data, file)
# 從文件反序列化列表
with open('list.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 輸出: [1, 2, 3, 4, 5]
這裡是序列化一個字典物件的樣子:
import pickle
# 可以序列化的物件示例
data = {'name': 'Alice', 'age': 30, 'is_student': False}
# 將物件序列化到文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
# 從文件反序列化物件
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data) # 輸出: {'name': 'Alice', 'age': 30, 'is_student': False}
想保存物件 — 調用 dump(),想加載 — 調用 load()。沒什麼難的。
9.3 序列化到字串
很多時候需要透過網路傳遞物件,因此需要把物件保存到字串而不是文件。為此,pickle 有 dumps 和 loads 方法,後面多了個 s。
將物件序列化和反序列化到字串(或位元數組)的基本步驟:
- 使用
pickle.dumps(obj)序列化物件。 - 使用
pickle.loads(data)反序列化物件。
將物件序列化和反序列化到字串
將物件序列化到字串(或位元數組)更簡單 — 你只需要調用一個方法 — dumps()。
範例:
import pickle
# 可以序列化的物件示例
data = {'name': 'Bob', 'age': 25, 'is_student': True}
# 將物件序列化到字串
serialized_data = pickle.dumps(data)
print(serialized_data)
# 從字串反序列化物件
loaded_data = pickle.loads(serialized_data)
print(loaded_data) # 輸出: {'name': 'Bob', 'age': 25, 'is_student': True}
9.4 序列化錯誤
有時候序列化過程中會出現錯誤。在這種情況下,pickle 模組會拋出異常:
-
pickle.PicklingError— 序列化過程中的錯誤。 -
pickle.UnpicklingError— 反序列化過程中的錯誤。
範例:
import pickle
data = {'key': 'value'}
try:
# 將物件序列化到文件
with open('data.pkl', 'wb') as file:
pickle.dump(data, file)
except pickle.PicklingError as e:
print(f"序列化錯誤: {e}")
try:
# 從文件反序列化物件
with open('data.pkl', 'rb') as file:
loaded_data = pickle.load(file)
print(loaded_data)
except pickle.UnpicklingError as e:
print(f"反序列化錯誤: {e}")
通常在程序運行時,作為程式設計師的你對序列化/反序列化錯誤無能為力。你能做的就是將其記錄在日誌中,以便將來查找原因。
這種錯誤的主要原因是物件格式的修改。當你把物件保存到文件後,程序更新了,物件有了新的字段或者舊的字段消失了,然後就嘗試用新類加載保存的舊物件…
這種情況經常在網路通信中出現— 2.18版本的程序發送的物件和3.1版本的程序期待的物件不太相同。這被稱為 遷移問題,在長期運行且需求量大的專案中經常遇到。
GO TO FULL VERSION