为何json.dump不调用__getstate__而pickle.dump会调用?
自定义类JSON序列化问题解析
问题场景
自定义类代码
from ctypes import * class PyClassExample: def __init__(self): self.path = '/some/unix/path/file.so' self.lib = CDLL(self.path) # 不可序列化的元素 self.arr = [1, 2, 3, 4] # 可序列化的元素 def __getstate__(self): state = self.__dict__.copy() del state['lib'] return state
报错信息
TypeError: Object of type PyClassExample is not JSON serializable
疑问
为何json.dump不调用__getstate__,但pickle.dump会调用它?json.dump采用什么机制获取传入对象的可序列化状态?
问题解答
1. 为什么json.dump不识别__getstate__
__getstate__是pickle模块专属的序列化协议方法,只有pickle在处理对象序列化时,会遵循Python的对象序列化协议,主动检测并调用该方法来获取对象的可序列化状态。而json模块和pickle是完全独立的两套序列化体系,json模块的设计目标是兼容JSON标准格式,它根本没有实现对pickle协议方法的支持,所以不会调用__getstate__。
2. json.dump的序列化机制
json模块的核心逻辑只支持Python内置的基础数据类型:dict、list、str、int、float、bool、None。对于自定义类的实例,json默认无法识别其结构,直接抛出类型错误。
要让自定义类实例支持json序列化,常用两种方案:
- 手动转换:在类中添加方法(比如
to_dict()),将实例转换为json支持的字典类型,再传入json.dump - 自定义编码器:继承
json.JSONEncoder,重写default方法,指定自定义类的转换规则
自定义编码器示例
import json class PyClassEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, PyClassExample): # 返回需要序列化的字段字典 return {"path": obj.path, "arr": obj.arr} # 其他类型交给父类处理 return super().default(obj) # 使用方式 obj = PyClassExample() with open("output.json", "w") as f: json.dump(obj, f, cls=PyClassEncoder)
内容的提问来源于stack exchange,提问作者Trick
相关产品推荐
相关产品推荐

