在現代的軟體開發中,序列化(Serialization)與反序列化(Deserialization)是不可或缺的技術。這些操作廣泛用於資料存儲、網路傳輸以及跨平台的數據交換。Python 提供了多種工具和庫來實現這些功能,例如 pickle、json 和 yaml 等。
本篇文章將詳細介紹序列化與反序列化的概念、Python 的內建支援,以及如何在不同場景中靈活運用。什麼是序列化與反序列化?
- 序列化:將物件(如字典、列表、類別實例)轉換為字節流或可傳輸的格式(如 JSON 字符串),以便存儲或傳輸。
- 反序列化:將字節流或傳輸的數據恢復為原始物件。
為什麼需要序列化?
- 儲存數據:將 Python 物件保存到文件中,供日後使用。
- 數據傳輸:在不同系統之間傳遞數據(例如通過 API 傳輸 JSON)。
- 持久化:在程序結束後保留運行中的物件狀態。
Python 常用的序列化工具
1. 使用 pickle
pickle 是 Python 的內建模組,用於將 Python 物件序列化為字節流,並可隨時反序列化。
基本用法
import pickle
# 原始物件
data = {"name": "Alice", "age": 25, "hobbies": ["reading", "cycling"]}
# 序列化:將物件轉換為字節流
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)
優缺點
- 優點:支持幾乎所有 Python 物件(包括類別與函數)。
- 缺點:只能在 Python 環境中使用,不適合跨平台傳輸。
2. 使用 json
json 是一種輕量級的數據交換格式,常用於網路應用程式中。Python 提供了內建的 json 模組。
基本用法
import json
# 原始物件
data = {"name": "Bob", "age": 30, "hobbies": ["gaming", "hiking"]}
# 序列化:將物件轉換為 JSON 字符串
json_string = json.dumps(data, indent=4)
print(json_string)
# 反序列化:將 JSON 字符串轉回 Python 物件
loaded_data = json.loads(json_string)
print(loaded_data)
序列化到文件
# 將 JSON 保存到文件
with open("data.json", "w") as file:
json.dump(data, file, indent=4)
# 從文件加載 JSON
with open("data.json", "r") as file:
loaded_data = json.load(file)
print(loaded_data)
優缺點
- 優點:可讀性高,支持跨平台數據交換。
- 缺點:不支持自定義物件(需要自定義編碼與解碼方法)。
處理自定義物件
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# 自定義序列化方法
def custom_encoder(obj):
if isinstance(obj, Person):
return {"name": obj.name, "age": obj.age}
raise TypeError("Type not serializable")
# 自定義反序列化方法
def custom_decoder(dct):
if "name" in dct and "age" in dct:
return Person(dct["name"], dct["age"])
return dct
person = Person("Charlie", 35)
# 序列化
json_string = json.dumps(person, default=custom_encoder, indent=4)
print(json_string)
# 反序列化
loaded_person = json.loads(json_string, object_hook=custom_decoder)
print(loaded_person.name, loaded_person.age)
3. 使用 yaml
yaml 是另一種常見的數據表示語言,語法簡潔且可讀性高。
基本用法
首先安裝 PyYAML:
pip install pyyamlimport yaml
# 原始物件
data = {"name": "Diana", "age": 28, "hobbies": ["painting", "skiing"]}
# 序列化:轉換為 YAML 格式
yaml_string = yaml.dump(data)
print(yaml_string)
# 反序列化:從 YAML 恢復物件
loaded_data = yaml.load(yaml_string, Loader=yaml.SafeLoader)
print(loaded_data)
優缺點
- 優點:語法簡潔,適合配置文件。
- 缺點:依賴額外的庫。
序列化與反序列化的進階應用
1. 文件數據持久化
將程序狀態保存為文件,方便下次載入。
import pickle
# 保存用戶設置
user_settings = {"theme": "dark", "font_size": 14}
with open("settings.pkl", "wb") as file:
pickle.dump(user_settings, file)
# 加載用戶設置
with open("settings.pkl", "rb") as file:
settings = pickle.load(file)
print(settings)
2. 通過 API 傳輸數據
利用 JSON 序列化與反序列化進行 HTTP 通訊。
import json
import requests
# 發送數據
data = {"username": "user123", "score": 95}
response = requests.post("https://example.com/api/submit", json=data)
print(response.status_code)
# 接收數據
response = requests.get("https://example.com/api/results")
result_data = response.json()
print(result_data)
常見錯誤與解決方法
1. 無法序列化自定義物件
如果直接嘗試序列化類別實例,會引發 TypeError。
解決方法:自定義編碼與解碼方法(如上 json 示例中的 custom_encoder 和 custom_decoder)。
2. 格式不兼容
例如,使用 pickle 保存的數據無法在不同 Python 版本中解析。
解決方法:選擇跨平台的格式,如 JSON 或 YAML。
3. 敏感數據存儲
序列化敏感數據時,可能引發安全問題(如反序列化惡意數據)。
解決方法:避免使用 pickle 處理不信任的數據,並考慮數據加密。
結論
本篇文章詳細介紹了 Python 序列化與反序列化的相關知識,涵蓋了 pickle、json 與 yaml 的基礎與進階用法。這些技術在數據存儲、傳輸以及程序狀態持久化中有著重要作用。希望這篇文章能幫助你掌握 Python 的序列化技術!



















