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

Python动态字典键序列化:如何映射响应动态键到dataclass类成员

解决方案

核心问题是响应row中的动态键不属于Row类的定义字段,直接传入构造方法会触发意外参数报错。你可以根据需求选择以下两种实现方案:


方案1:从custom_fields提取值映射到固定字段(更稳定)

观察到响应中custom_fields已经包含了所有动态键对应的id和值映射,完全不需要依赖外层的动态键,直接从该字段提取值绑定到x/y即可,外层动态键可以直接忽略:

from dataclasses import dataclass
from typing import List


@dataclass
class Serialisable:
  
    @classmethod
    def from_dict(cls, d):
        if d is not None:
            return cls(**d)


@dataclass
class CustomField(Serialisable):
    id: int
    value: str


@dataclass
class Row(Serialisable):
    x: str   # 对应id 1900000084913的字段值
    y: str   # 对应id 360018501198的字段值
    custom_fields: List[CustomField]

    @classmethod
    def from_dict(cls, d):
        if d is not None:
            custom_fields_data = d.pop("custom_fields", None)
            custom_fields = []
            if custom_fields_data is not None:
                custom_fields = [CustomField.from_dict(field) for field in custom_fields_data]
            # 直接从custom_fields提取对应id的值,完全忽略外层动态键
            x = next(field.value for field in custom_fields if field.id == 1900000084913)
            y = next(field.value for field in custom_fields if field.id == 360018501198)
            return cls(x=x, y=y, custom_fields=custom_fields)


@dataclass
class ResponseObject(Serialisable):
    rows: List[Row]

    @classmethod
    def from_dict(cls, d):
        if d is not None:
            kwargs = dict(d)
            rows = kwargs.pop("rows", None)
            if rows is not None:
                kwargs["rows"] = [
                    Row.from_dict(row) for row in rows
                ]

            return cls(**kwargs)


if __name__ == "__main__":
    response = {
        'rows': [
            {
                '1900000084913': '222222',
                '360018501198': '4003112',
                'custom_fields': [
                    {'id': 360018501198, 'value': '4003112'},
                    {'id': 1900000084913, 'value': '222222'}
                ]
            }
        ]
    }
    response_obj = ResponseObject.from_dict(response)
    print(response_obj)
    # 输出结果:ResponseObject(rows=[Row(x='222222', y='4003112', custom_fields=[CustomField(id=360018501198, value='4003112'), CustomField(id=1900000084913, value='222222')])])

方案2:存储所有动态键到字典(扩展性更强)

如果动态键的数量不固定,后续可能新增,你可以新增一个字段存储所有动态键值对,不需要提前定义固定字段:

@dataclass
class Row(Serialisable):
    dynamic_fields: dict  # 存储所有动态键值对
    custom_fields: List[CustomField]

    @classmethod
    def from_dict(cls, d):
        if d is not None:
            d_copy = dict(d)
            custom_fields_data = d_copy.pop("custom_fields", None)
            if custom_fields_data is not None:
                custom_fields = [CustomField.from_dict(field) for field in custom_fields_data]
            # 剩余的所有键都是动态键,统一存入dynamic_fields
            dynamic_fields = d_copy
            return cls(dynamic_fields=dynamic_fields, custom_fields=custom_fields)

后续可以通过row.dynamic_fields['1900000084913']的方式获取对应动态键的值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:39:04