Python json 模組預設僅支援內建型別。若需序列化自訂類別實例,需透過 default 與 object_hook 參數自訂轉換邏輯。本文以 Student 類別為例詳細說明。
import json
class Student(object):
def __init__(self, name, age, score):
self.name, self.age, self.score = name, age, score
s = Student('Bob', 20, 88)
json.dumps(s) # TypeError
default 接受一個函式,將不可序列化物件轉為可序列化型別(通常是 dict)。
def student2dict(std):
return {'name': std.name, 'age': std.age, 'score': std.score}
json.dumps(s, default=student2dict)
# '{"age": 20, "score": 88, "name": "Bob"}'
json.dumps(s, default=lambda obj: obj.__dict__)
多數類別實例擁有 __dict__ 屬性儲存實例變數;定義 __slots__ 的類別除外。
object_hook 接受一個函式,將解析出的 dict 轉為目標物件。
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
stu = json.loads(json_str, object_hook=dict2student)
print(stu) # <__main__.Student object at 0x...>
json.dumps/loads 只需一個必填參數即可滿足 90% 需求;進階需求時再透過關鍵字參數擴充,兼顧「簡單易用」與「高度可擴充」,是 API 設計的經典範例。
default=lambda obj: obj.__dict__ 或專用函式。object_hook=dict2student。