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

自定义Serialisable类JSON序列化异常及c_make_encoder相关问询

问题解答

1. 为Serialisable类补充内容以支持json.dumps()序列化

Python的JSON模块在使用C实现的c_make_encoder时,只会识别原生dict类型,不会触发Python层面的字典协议方法。要解决无indent参数时的序列化问题,可采用以下几种方案:

方案一:实现__iter__方法

C编码器会通过迭代对象获取键,因此实现__iter__返回可序列化实例变量的键迭代器:

class Serialisable(dict):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 处理实例变量的逻辑,示例中将传入参数设为实例属性
        for k, v in kwargs.items():
            setattr(self, k, v)
    
    def __iter__(self):
        # 返回非下划线开头的实例属性键(可根据实际调整过滤规则)
        return iter(k for k in self.__dict__ if not k.startswith('_'))

方案二:自定义JSON编码器并指定使用

无需修改Serialisable类,调用json.dumps()时通过cls参数指定自定义编码器:

import json

class SerialisableEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Serialisable):
            # 将实例变量转换为字典(过滤规则可自定义)
            return {k: v for k, v in obj.__dict__.items() if not k.startswith('_')}
        return super().default(obj)

# 使用示例
obj = Serialisable(name="test", value=123)
print(json.dumps(obj, cls=SerialisableEncoder))

方案三:覆盖dict的核心方法

让C编码器能通过标准字典方法获取键值对:

class Serialisable(dict):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        for k, v in kwargs.items():
            setattr(self, k, v)
    
    def keys(self):
        return (k for k in self.__dict__ if not k.startswith('_'))
    
    def items(self):
        return ((k, self.__dict__[k]) for k in self.__dict__ if not k.startswith('_'))
    
    def __getitem__(self, key):
        return self.__dict__[key]

2. c_make_encoder的代码位置

c_make_encoder是CPython中JSON模块的C扩展实现,对应的代码位于Python源代码的Modules/_json.c文件中。具体逻辑在PyMakeEncoder函数(对应Python层的c_make_encoder)以及encode_dict函数内,你可以查看对应CPython版本的_json.c文件找到相关实现。

内容的提问来源于stack exchange,提问作者Nuno

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:25:18