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

如何将Python dataclass转换为带@前缀key的指定格式JSON

Python dataclass 自定义JSON序列化实现方案

实现思路

  • 递归遍历dataclass实例,读取每个类内部定义的Meta属性生成指定键名
  • 优先处理RType类型的字段,生成带@前缀的@r_type键
  • 嵌套dataclass自动递归序列化,保证所有层级都符合格式要求
  • 完全依赖Python标准库,无需引入第三方依赖

完整实现代码

from dataclasses import is_dataclass
import json
from dataclasses import dataclass

def serialize(obj):
    # 非dataclass类型直接返回原值
    if not is_dataclass(obj):
        return obj
    res = {}
    # 遍历所有字段处理
    for field_name in obj.__dataclass_fields__:
        field_val = getattr(obj, field_name)
        serialized_val = serialize(field_val)
        # 处理RType类的特殊映射规则
        if is_dataclass(field_val) and hasattr(field_val, 'Meta'):
            meta = field_val.Meta
            if hasattr(meta, 'name') and hasattr(meta, 'content'):
                res[meta.name] = getattr(field_val, meta.content)
                continue
        # 处理当前类的Meta配置规则
        if hasattr(obj, 'Meta'):
            meta = obj.Meta
            if hasattr(meta, 'name') and hasattr(meta, 'content') and field_name == meta.content:
                res[meta.name] = serialized_val
                continue
        # 普通字段直接用字段名作为键
        res[field_name] = serialized_val
    return res

# 原有业务dataclass定义
@dataclass
class RType:
    type_name: str

    class Meta:
        name = '@r_type'
        content = 'type_name'

@dataclass
class Options:
    type: RType
    content: str

    class Meta:
        name = 'options'
        content = 'content'

测试验证

示例1测试代码

# 构造示例1对应数据
rtype_init = RType(type_name='init')
rtype_options = RType(type_name='options')
options = Options(type=rtype_options, content='some_options')

# 定义匹配示例1结构的顶层dataclass
@dataclass
class InitRoot:
    type: RType
    options: Options

root = InitRoot(type=rtype_init, options=options)
# 输出JSON结果
print(json.dumps(serialize(root), indent=2, ensure_ascii=False))

示例1输出结果

{
  "@r_type": "init",
  "options": {
    "@r_type": "options",
    "options": "some_options"
  }
}

示例2测试代码

# 定义匹配示例2结构的Directory类
@dataclass
class Directory:
    type: RType
    content: str

    class Meta:
        name = 'directory'
        content = 'content'

# 构造示例2对应数据
rtype_dir_init = RType(type_name='dir_init')
rtype_directory = RType(type_name='directory')
directory = Directory(type=rtype_directory, content='path_to')

# 定义匹配示例2结构的顶层dataclass
@dataclass
class DirRoot:
    type: RType
    directory: Directory

root = DirRoot(type=rtype_dir_init, directory=directory)
# 输出JSON结果
print(json.dumps(serialize(root), indent=2, ensure_ascii=False))

示例2输出结果

{
  "@r_type": "dir_init",
  "directory": {
    "@r_type": "directory",
    "directory": "path_to"
  }
}

扩展说明

如果需要支持列表、字典等复合类型字段,只需在serialize函数中增加对应类型的判断逻辑,递归处理容器内的每个元素即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:15:03