使用 pickle

Python SELF TW
等級 22 , 課堂 1
開放

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 序列化到文件

文件序列化的基本步驟:

  1. 以位元寫入模式打開文件 (wb)
  2. 使用 pickle.dump(obj, file) 序列化物件。
  3. 使用 pickle.load(file) 反序列化物件。
  4. 關閉文件。

將物件序列化和反序列化到文件

其實 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 序列化到字串

很多時候需要透過網路傳遞物件,因此需要把物件保存到字串而不是文件。為此,pickledumpsloads 方法,後面多了個 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版本的程序期待的物件不太相同。這被稱為 遷移問題,在長期運行且需求量大的專案中經常遇到。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION