88.~92 project- Tic Tac Toe Game
93. Serialization and Deserialization
94. Pickle
95. Shelve
93. Serialization and Deserialization
在程式設計中,**序列化(Serialization)和反序列化(Deserialization)**是兩個常見的概念,主要與資料的轉換和儲存有關。
簡單來說,這兩個過程是資料在不同形式之間轉換的過程。
1. 序列化 (Serialization)
序列化是將資料結構或物件狀態轉換為可以儲存或傳輸的格式,通常是二進制或字串格式。
這個過程使得物件可以被儲存在檔案中、傳輸到網路上、或儲存在資料庫中,
且能夠在未來再進行反序列化(還原)以恢復成原來的物件。
簡單的例子:
假設你有一個 Python 字典 {“name”: “Alice”, “age”: 30},你想將它寫入文件中,
或者將它發送到網路上,你需要將它「序列化」成某種格式(如 JSON 或 Pickle 格式)。
在這種情況下,序列化就是將 Python 物件轉換為字串或二進制格式,以便進行儲存或傳輸。
在 Python 中,常用的序列化格式包括:
- JSON(JavaScript Object Notation):通常用於資料交換,尤其在 Web 開發中。
- Pickle:Python 自有的序列化格式,適用於 Python 物件的儲存和重建。
2. 反序列化 (Deserialization)
反序列化是序列化的反向過程,將儲存或傳輸過來的資料恢復為原來的物件或資料結構。也就是說,將二進制或字串格式的資料轉換回程式可以處理的物件。
簡單的例子:
假設你有一個序列化後的資料(例如 JSON 格式的字串)‘{“name”: “Alice”, “age”: 30}’,你想將它轉換回 Python 字典物件,這時候就需要進行反序列化。
在 Python 中,常用的反序列化方式包括:
- JSON 反序列化(json.loads())
- Pickle 反序列化(pickle.load())
- 序列化與反序列化的應用範例
JSON 格式的序列化與反序列化:
import json
# 物件
person = {"name": "Alice", "age": 30}
# 序列化: 將 Python 字典轉換為 JSON 格式的字串
json_data = json.dumps(person)
print("Serialized data:", json_data)
# 反序列化: 將 JSON 格式的字串轉換回 Python 字典
person_object = json.loads(json_data)
print("Deserialized data:", person_object)
在這個例子中:
- json.dumps():將 Python 字典轉換為 JSON 格式的字串,這就是序列化。
- json.loads():將 JSON 格式的字串轉換回 Python 字典,這就是反序列化。
Pickle 格式的序列化與反序列化:
import pickle
# 物件
person = {"name": "Alice", "age": 30}
# 序列化: 將 Python 物件轉換為二進制格式
with open("person.pkl", "wb") as file:
pickle.dump(person, file)
# 反序列化: 從檔案中讀取二進制格式並轉換回 Python 物件
with open("person.pkl", "rb") as file:
loaded_person = pickle.load(file)
print("Deserialized data:", loaded_person)
在這個例子中:
- pickle.dump():將 Python 物件轉換為二進制格式並儲存在檔案中,這就是序列化。
- pickle.load():將檔案中的二進制資料反序列化回 Python 物件。
為什麼要使用序列化和反序列化?
儲存和傳輸資料:
透過序列化,可以將複雜的資料結構(例如 Python 物件、字典、列表等)轉換為便於儲存或傳輸的格式。反序列化則可以將其轉換回原本的格式,讓程式能夠繼續處理這些資料。
Web API 與資料交換:
網頁應用程序、API、微服務等經常使用 JSON 來序列化和反序列化資料,以便於在不同的系統之間進行資料交換。
儲存 Python 物件:
在 Python 中,你可以使用 Pickle 模組來將物件儲存到磁碟上(例如:保存模型、訓練資料、程式狀態等),並在需要時反序列化回來。
避免資料丟失:
透過序列化,你可以保證資料在傳輸或儲存過程中不會丟失或改變,並且能夠以一致的方式還原。
結論
序列化是將資料結構或物件轉換為可以儲存或傳輸的格式(如字串或二進制)。
反序列化是將這些格式轉換回原來的資料結構或物件。
這些技術對於資料儲存、網路資料傳輸和跨平台應用程式的開發至關重要。
什麼是 Pickle?
Pickle 是 Python 提供的一個內建模組,
專門用於將 Python 物件序列化(serialize)和反序列化(deserialize)。它將 Python 物件轉換為二進制格式,便於儲存到檔案或傳輸到網路上,並且能夠隨時還原成原始的 Python 物件。
Pickle 的主要用途
- 儲存 Python 物件到檔案:
將變數(如列表、字典、類別等)儲存到磁碟,以便在未來的程式執行中重複使用。 - 物件的網路傳輸:
將 Python 物件序列化後,可以透過網路傳輸並在接收端反序列化還原。 - 保存程式狀態:
在某些情況下,可以用來保存程式的中間狀態,稍後繼續執行。
如何使用 Pickle?
- 匯入模組
要使用 Pickle,首先要匯入 pickle 模組:
import pickle
- 將資料序列化並儲存到檔案
使用pickle.dump()
方法,可以將 Python 物件序列化後儲存在檔案中:
# 要儲存的物件
data = {"name": "Alice", "age": 30, "languages": ["Python", "C++", "Java"]}
# 打開檔案,以二進制寫入模式(wb)
with open("data.pkl", "wb") as file:
pickle.dump(data, file)
print("資料已序列化並儲存到檔案 data.pkl")
- 從檔案中讀取資料並反序列化
使用 pickle.load() 方法,可以將儲存的二進制格式資料反序列化為 Python 物件:
# 打開檔案,以二進制讀取模式(rb)
with open("data.pkl", "rb") as file:
loaded_data = pickle.load(file)
print("從檔案中還原的資料:", loaded_data)
pickle常見情境:
- 保存複雜的 Python 資料結構
當資料結構包含像是列表、字典,甚至自訂類別的物件,並且希望在稍後還原使用時,pickle 是一個快速且方便的工具。
例如:
- 中間處理結果的保存和讀取(如數據分析中的數據快取)。
- 機器學習中訓練後的模型保存(如 scikit-learn 使用 pickle 保存模型)。
- 程序之間的數據傳遞
如果有多個 Python 程序需要共享數據,可以透過 pickle 序列化資料,將其儲存到檔案或傳遞到其他程序。
例如:
- 保存狀態以供另一個程序讀取。
- 透過網路或管道傳遞序列化的物件。
-
保存和還原工作進度
如果程式執行需要很長時間,pickle 可用於保存執行的中間狀態,避免重複執行相同的操作。
例如:
長時間運行的數據處理工作中保存進度,然後在程序崩潰或中斷時還原。 -
快速測試或臨時保存
在開發和測試中,pickle 可以用來臨時保存數據以快速調試或測試功能。
使用 pickle 的注意事項
安全性問題:
pickle 無法防範惡意數據,因此不要反序列化(pickle.load)不受信任的來源的數據。
與 JSON 的選擇:
當數據只包含基本類型(如字典、列表、數字、字符串等)時,應優先使用 JSON,因為 JSON 可讀性高且跨語言支持。
若數據包含複雜 Python 特定結構(如自訂類別或函數),可使用 pickle。
什麼時候不應該使用 pickle?
- 需要跨語言操作:如果需要和非 Python 程序共享數據,應使用 JSON 或其他標準格式。
- 需要數據長期保存:如果數據需要長期保存或存入資料庫,pickle 並不是最佳選擇,因為它受 Python 版本影響且可讀性差。
Shelve
shelve 是 Python 標準庫中一個方便的模組,
用於將 Python 物件存儲到一個類似字典的持久化對象中。
它結合了 pickle 的序列化能力和簡單的鍵值存取方式,
使得開發者可以輕鬆地保存和讀取 Python 的數據結構到文件中,
而不需要自己處理文件操作和序列化細節。
shelve 的特點
- 類似字典的操作方式:
- 用法和字典類似,可以透過鍵值對儲存和讀取數據。
- 使用時只需記住操作字典的方法,例如 db[key] = value。
- 自動序列化:
- 支持將多種類型的 Python 物件(如字典、列表、自定義對象)直接保存到檔案中,底層使用 pickle 處理序列化。
- 持久化存儲:
- 數據保存在硬碟文件中,程序重啟後仍能讀取。
- 效率較高:
- 因為只在需要時加載數據,對於大數據集,比 JSON 或單一 pickle 文件更有效。
- 限制:
- 只能使用字符串作為鍵。
- 存儲的對象需可被 pickle 序列化。
- 與數據庫的設計不同,適用於簡單數據存儲而非高併發操作。
基本使用範例
import shelve
# 開啟一個 shelve 檔案
with shelve.open("mydata") as db:
# 儲存數據
db["name"] = "Alice"
db["age"] = 30
db["skills"] = ["Python", "C++", "Java"]
# 從檔案中讀取數據
print(db["name"]) # 輸出: Alice
print(db["age"]) # 輸出: 30
print(db["skills"]) # 輸出: ['Python', 'C++', 'Java']
特性 | Shelve | Pickle | JSON | SQLite |
---|---|---|---|---|
儲存格式 | 類似字典的檔案 | 二進制檔案 | 文本檔案 | 數據庫檔案 |
可讀性 | 低 | 低 | 高 | 高 |
數據類型支持 | 任意 Python 對象 | 任意 Python 對象 | 基本數據類型 | 基本數據類型 |
操作方式 | 類似字典 | 程序控制序列化/反序列化 | 程序控制序列化/反序列化 | SQL 操作 |
應用場景 | 小型數據持久化存儲 | 任意序列化需求 | 跨語言數據傳輸 | 結構化數據存儲 |