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

如何让json.dumps/loads支持传入Encoder/Decoder实例而非类

能否让json.dumps/loads支持接收Encoder/Decoder实例而非类作为参数?

问题背景

参考如下自定义JSON编码器的基础示例:

import json
from typing import Any

class MyNumber:
    def __init__(self, num):
        self.num = num

class MultEncoder(json.JSONEncoder):
    """编码MyNumber实例时做乘法处理"""
    def default(self, o: Any) -> Any:
        if isinstance(o, MyNumber):
            return o.num*2
        return super().default(o)

上述代码的基础运行效果:

>>> json.dumps({"a": MyNumber(5)}, cls=MultEncoder)
'{"a": 10}'

当需要动态配置编码时的乘数因子时,尝试编写带自定义初始化参数的编码器:

class MultEncoder(json.JSONEncoder):
    """编码MyNumber实例时按指定因子做乘法处理"""
    def __init__(self, factor, *args, **kwargs):
        self.factor = factor        
        super().__init__(*args, **kwargs)

    def default(self, o: Any) -> Any:
        if isinstance(o, MyNumber):
            return o.num*self.factor
        return super().default(o)

执行json.dumps({"a": MyNumber(5)}, cls=MultEncoder(7))时会抛出如下错误:

TypeError: 'MultEncoder' object is not callable

报错原因是json.dumps的cls参数要求传入类对象,而非类的实例。

已知约束

  • 无法自定义封装my_json_dumps/my_json_loads包装函数,仅能控制调用json.dumps、json.loads时传入的编码器/解码器类
  • 实际业务场景中,编码器/解码器需要读取数据库连接凭证及其他动态配置信息,无法将参数硬编码在类中

可行实现方案

不需要修改标准库json模块逻辑,也不需要封装dumps/loads方法,通过类工厂+闭包动态生成绑定了配置参数的编码器/解码器类即可,完全兼容原生cls参数的传参要求。

编码器实现

编写接收动态配置、返回定制化Encoder子类的工厂函数:

def build_mult_encoder(factor: int):
    # 内部定义绑定了配置参数的编码器子类
    class ConfiguredMultEncoder(json.JSONEncoder):
        def default(self, o: Any) -> Any:
            if isinstance(o, MyNumber):
                return o.num * factor
            return super().default(o)
    return ConfiguredMultEncoder

调用方式

直接将工厂生成的类传入cls参数即可,无需传入实例:

>>> json.dumps({"a": MyNumber(5)}, cls=build_mult_encoder(7))
'{"a": 35}'
>>> json.dumps({"a": MyNumber(5)}, cls=build_mult_encoder(3))
'{"a": 15}'

如果需要读取数据库凭证等复杂动态配置,只需要将工厂函数的入参替换为对应配置项即可,所有配置会在生成类时绑定到闭包作用域中,编码器实例化时无需额外传参,完全符合json模块对cls参数的类型要求。

Decoder的动态配置实现逻辑完全一致:编写接收动态配置的类工厂函数,返回定制后的json.JSONDecoder子类,直接传入json.loads的cls参数即可正常使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 05:21:46