Python 標準函式庫中的資料儲存與序列化:json、pickle、csv
若要將資料寫入檔案或透過網路傳輸,必須先進行序列化(Serialization)。Python 為此提供了三種性質迥異的標準工具:json、pickle、csv。

json:可讀文本格式,跨語言交換友好pickle:將 Python 物件直接存成二進位格式,功能強大但存在風險csv:最簡單的表格資料文本格式,通用性高
本文將根據「資料用途」整理選擇三個模組的感覺。
1. JSON
1.1 概述
JSON(JavaScript Object Notation)是文字基礎且語言獨立的格式。設定檔、API 回應/請求、日誌等「適合與其他系統交換」的資料常用此格式。Python 直接使用 json 模組處理。
1.2 核心 API(常用)
json.dump(obj, fp, ...)/json.load(fp, ...):寫入/讀取檔案json.dumps(obj, ...)/json.loads(s, ...):轉成字串/從字串還原
值得記住的選項:
ensure_ascii=False:不將非 ASCII 字元轉成 \uXXXX,直接保留原文indent=2:美化輸出default=...:提供「跳過」函式,處理 JSON 無法序列化的型別
1.3 使用範例(基本)
import json
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "Data Science"]
}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
print(loaded)
1.4 方便處理 JSON 的「型別限制」
JSON 只天然支援 dict、list、str、int/float、bool、None。例如 datetime 需要額外處理。可透過 default 參數傳入函式,將不支援型別轉成 JSON 可接受的型別。
import json
from datetime import datetime, timezone
payload = {"created_at": datetime.now(timezone.utc)}
def to_jsonable(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not JSON serializable: {type(obj)!r}")
s = json.dumps(payload, default=to_jsonable, ensure_ascii=False)
print(s)
1.5 優缺點
優點
- 語言獨立,易於交換與分享
- 文字格式,易於除錯與版本控制
- 不像
pickle那樣在載入時執行程式碼
缺點
- 型別表達有限(如
datetime、set、Decimal、二進位資料) - 大量資料時,容量與速度可能不如二進位格式
2. Pickle
2.1 概述
pickle 是為「將 Python 物件以 Python 原樣」序列化的方式。輸出為二進位資料(bytes),再次載入時可得到近乎相同的物件。
pickle 特別適用於:
- 想保留自訂類別實例、巢狀資料結構、已訓練模型/設定物件等
- 不需要與其他語言交換
相反,若需跨語言或信任度低的來源,應避免使用。
2.2 核心 API(最常用 4 個)
pickle.dump(obj, file, protocol=...):寫入檔案pickle.load(file):讀取檔案pickle.dumps(obj, protocol=...):轉成 bytespickle.loads(data):從 bytes 讀取
import pickle
data = {"a": [1, 2, 3], "b": ("x", "y")}
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
with open("data.pkl", "rb") as f:
loaded = pickle.load(f)
print(loaded)
2.3 protocol 是什麼?為何要注意?
protocol 是 pickle 存檔時使用的「格式版本」。不同版本會影響檔案大小、速度與支援功能。
- 未指定時,Python 會選擇「最適合目前環境」的預設值
- 只在以下兩種情況下需要手動設定: 1. 與非常舊的 Python 版本保持相容 2. 想明確使用最新、最快的格式
常見做法是使用 pickle.HIGHEST_PROTOCOL(目前最高的協定號)。
import pickle
with open("data.pkl", "wb") as f:
pickle.dump({"x": 1}, f, protocol=pickle.HIGHEST_PROTOCOL)
2.4 Pickle 的真正注意點(重要)
pickle.load() / pickle.loads() 會執行資料中包含的「還原邏輯」。因此,載入不可信的 pickle 可能導致惡意程式執行。
- 安全做法:不要載入未知來源的
.pkl檔 - 若需交換,建議改用
json等文字格式
2.5 優缺點
優點
- 能存任何 Python 物件(幾乎無限制)
- 通常比
json更快、更方便(尤其是複雜物件)
缺點
- 安全風險(不可信來源不可載入)
- 只適用於 Python,無法跨語言
- 物件定義變更可能破壞舊 pickle(版本相容問題)
3. CSV
3.1 概述
CSV(Comma-Separated Values)是最簡單的表格資料格式。常見於試算表、資料匯出/匯入、簡易日誌等。
3.2 核心 API(常用)
csv.reader、csv.writer:基於列表csv.DictReader、csv.DictWriter:基於字典(大多使用此方式)
3.3 使用範例(DictWriter/DictReader)
import csv
data = [
{"name": "Alice", "age": 30, "city": "Seoul"},
{"name": "Bob", "age": 25, "city": "Busan"},
]
with open("people.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age", "city"])
writer.writeheader()
writer.writerows(data)
with open("people.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
loaded = list(reader)
print(loaded)
3.4 CSV 的三個注意點
- 一定要加
newline="":避免 Windows 產生雙行 - 所有資料皆為字串:讀取後需自行轉型
- 分隔符/引號/換行可能出現在資料中:使用
csv模組可自動處理
3.5 優缺點
優點
- 輕量、通用(大多工具可讀寫)
- 對表格資料極簡易處理
缺點
- 無法表達巢狀結構(如列表內列表、字典巢狀)
- 缺少型別資訊,需手動轉換
4. 比較 & 選擇指引
| 項目 | JSON | Pickle | CSV |
|---|---|---|---|
| 語言相容 | 非常好 | 只適用 Python | 非常好 |
| 可讀性 | 高 | 低(二進位) | 高 |
| 型別表達 | 限制 | 非常高 | 限制 |
| 安全性 | 相對安全 | 需注意 | 相對安全 |
| 資料結構 | 樹狀(巢狀) | 「Python 物件原樣」 | 表格(行/列) |
一句話總結:
- 跨系統交換 →
json - 完整保留 Python 物件 →
pickle(但來源必須可信) - 表格輸出/輸入 →
csv
5. 同一資料用三種方式儲存/還原
以下示範同一資料分別以 json、pickle、csv 儲存並讀取。
import json, pickle, csv
data = [
{"id": 1, "name": "Alice", "score": 95.5},
{"id": 2, "name": "Bob", "score": 88.0},
]
# 1) JSON
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
json_loaded = json.load(f)
# 2) Pickle
with open("data.pkl", "wb") as f:
pickle.dump(data, f)
with open("data.pkl", "rb") as f:
pickle_loaded = pickle.load(f)
# 3) CSV
with open("data.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["id", "name", "score"])
writer.writeheader()
writer.writerows(data)
with open("data.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
csv_loaded = [
{"id": int(row["id"]), "name": row["name"], "score": float(row["score"])}
for row in reader
]
print(json_loaded)
print(pickle_loaded)
print(csv_loaded)
重點:
- CSV 讀取後需手動轉型
- Pickle 方便但須注意來源安全
6. 結語
僅靠 Python 標準函式庫,就能覆蓋資料儲存與序列化的廣泛需求。
- 需要跨語言或人可讀 →
json - 想保留 Python 物件完整 →
pickle - 想簡單輸出表格 →
csv
根據「資料形態」與「目的」選擇合適模組,即可快速、乾淨地完成儲存與還原。