You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:15:35