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

如何使用cattrs将JSON结构化为支持额外字段的attrs类?

解决方案

原实现的问题在于绕过了cattrs的默认结构化逻辑,直接将原始字典参数传入自定义构造方法,因此cattrs提供的类型转换、嵌套类结构化等内置能力都没有生效,才会出现字段类型不符合预期的问题。

正确实现代码

import attr
from cattr.preconf.json import make_converter


@attr.s(auto_detect=True)
class ClassWithExtras:
    foo: int


converter = make_converter()

def structure_with_extras(attribs: dict, cls):
    # 获取当前类已定义的所有attrs字段名
    defined_field_names = attr.fields_dict(cls).keys()
    # 拆分已知字段和额外字段
    known_attrs = {k: v for k, v in attribs.items() if k in defined_field_names}
    extra_attrs = {k: v for k, v in attribs.items() if k not in defined_field_names}
    # 调用cattrs默认逻辑处理已知字段,自动完成类型转换
    instance = converter.structure(known_attrs, cls)
    # 挂载额外字段到实例
    for k, v in extra_attrs.items():
        setattr(instance, k, v)
    return instance

# 为所有ClassWithExtras的子类注册结构钩子
converter.register_structure_hook_func(
    lambda cls: issubclass(cls, ClassWithExtras),
    structure_with_extras
)

# 测试
structured = converter.structure({"foo": "2", "bar": 5}, ClassWithExtras)
print(structured.foo + structured.bar) # 输出7,类型转换正常

实现逻辑说明

  • 无需自定义类的__init__方法,保留attrs自动生成的构造方法即可
  • 结构化时先拆分入参字典:已在类中定义的字段交给cattrs默认逻辑处理,自动完成类型转换、校验、嵌套类结构化等原有操作
  • 额外字段直接挂载到生成的实例上,既保留了cattrs的全部能力,又实现了额外字段的存储需求
  • 所有继承自ClassWithExtras的子类都会自动适配该逻辑,无需重复注册钩子

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:09:04