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

如何在Python Dataclass中实现序列化与反序列化的字段键映射

使用Python Dataclass实现字段名双向映射的序列化/反序列化

方案一:用Pydantic(推荐)

Pydantic对dataclass有原生支持,通过Field的alias参数可轻松实现字段名的双向映射,该参数同时支持反序列化(输入键映射到类属性)和序列化(类属性转换为指定键名)。

步骤1:安装Pydantic

pip install pydantic

步骤2:定义带别名的Dataclass

用Pydantic的dataclass替代原生版本,通过Field指定别名:

from pydantic.dataclasses import dataclass
from pydantic import Field

@dataclass
class MySchema:
    account_id: int | None = Field(default=None, alias='accountId', metadata=dict(required=False))
    short_key: int | None = Field(default=None, alias='shortKey', metadata=dict(required=False))

步骤3:反序列化(JSON/字典转Dataclass)

直接通过类构造方法传入原始数据即可:

# 原始输入数据
raw_data = {"accountId": 123, "shortKey": 54}

# 反序列化
schema = MySchema(**raw_data)
print(schema.account_id)  # 输出: 123
print(schema.short_key)   # 输出: 54

步骤4:序列化(Dataclass转字典/JSON)

使用model_dump()方法并指定by_alias=True,即可输出带别名的键值对:

# 序列化为带别名的字典
serialized_data = schema.model_dump(by_alias=True)
print(serialized_data)  # 输出: {'accountId': 123, 'shortKey': 54}

# 转换为JSON字符串
import json
json_str = json.dumps(serialized_data)
print(json_str)  # 输出: {"accountId": 123, "shortKey": 54}

方案二:原生Dataclass手动实现(无第三方库)

若不想依赖第三方库,可自行编写工具函数处理键名映射:

步骤1:定义原生Dataclass

在metadata中自定义data_key标识映射的字段名:

from dataclasses import dataclass, field, asdict

@dataclass
class MySchema:
    account_id: int | None = field(default=None, metadata=dict(required=False, data_key='accountId'))
    short_key: int | None = field(default=None, metadata=dict(required=False, data_key='shortKey'))

步骤2:编写反序列化函数

将输入字典的键转换为类属性名:

def deserialize_to_schema(raw_data: dict) -> MySchema:
    # 构建映射关系:data_key → 类属性名
    key_map = {
        field.metadata['data_key']: field.name
        for field in MySchema.__dataclass_fields__.values()
        if 'data_key' in field.metadata
    }
    # 转换键名并初始化dataclass
    mapped_data = {key_map[k]: v for k, v in raw_data.items() if k in key_map}
    return MySchema(**mapped_data)

# 测试反序列化
raw_data = {"accountId": 123, "shortKey": 54}
schema = deserialize_to_schema(raw_data)
print(schema.account_id)  # 输出: 123

步骤3:编写序列化函数

将类属性名转换为data_key指定的字段名:

def serialize_from_schema(schema: MySchema) -> dict:
    # 构建映射关系:类属性名 → data_key
    key_map = {
        field.name: field.metadata['data_key']
        for field in MySchema.__dataclass_fields__.values()
        if 'data_key' in field.metadata
    }
    # 转换键名并过滤空值
    raw_dict = asdict(schema)
    serialized_data = {key_map[k]: v for k, v in raw_dict.items() if k in key_map and v is not None}
    return serialized_data

# 测试序列化
serialized_data = serialize_from_schema(schema)
print(serialized_data)  # 输出: {'accountId': 123, 'shortKey': 54}

关于data_key的说明

data_key并非原生Python dataclass的内置参数,它多是marshmallow等第三方库的字段别名配置项。而Pydantic的alias参数完全满足你的双向映射需求,是处理这类场景最简洁的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:27:30