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

如何从含多余键值对的字典实例化attrs类?

问题:使用attrs类初始化时如何忽略字典中的多余键值对

我用attrs.define装饰了一个类,定义了必要属性:

import attrs

@attrs.define
class MyAttrsClass:
    important1 = attrs.field(type = int)
    important2 = attrs.field(type = str)
    [...]

原本用字典解包初始化实例是正常的:

test_dict = {'important1': 100, 'important2': 'foo'}
ci = MyAttrsClass(**test_dict)

但实际场景中,字典是json.loads反序列化的API响应,包含大量无用键值对,此时会报错:TypeError: MyAttrsClass.__init__() got an unexpected keyword argument 'XYZ'。

想问能不能直接初始化MyAttrsClass实例并自动丢弃多余元素?必须手动删除字典条目吗?有没有更优的attrs解决方案?


解决方案

不需要手动删除字典条目,利用attrs的内置工具就能优雅解决,下面是两种常用方法:

方法1:临时过滤字典后初始化

借助attrs.fields()获取类的所有字段名,过滤输入字典只保留有效键,再解包初始化:

import attrs

@attrs.define
class MyAttrsClass:
    important1 = attrs.field(type=int)
    important2 = attrs.field(type=str)

# 模拟带多余字段的API响应
api_response = {'important1': 100, 'important2': 'foo', 'XYZ': '无用字段', 'extra_key': 'bar'}

# 提取类中允许的字段键
allowed_keys = {field.name for field in attrs.fields(MyAttrsClass)}
# 过滤字典
filtered_data = {k: v for k, v in api_response.items() if k in allowed_keys}

# 正常初始化实例
ci = MyAttrsClass(**filtered_data)

方法2:给类添加专用类方法(推荐)

给MyAttrsClass定义一个from_dict类方法,把过滤逻辑封装进去,后续调用更简洁:

import attrs

@attrs.define
class MyAttrsClass:
    important1 = attrs.field(type=int)
    important2 = attrs.field(type=str)

    @classmethod
    def from_dict(cls, data):
        allowed_keys = {field.name for field in attrs.fields(cls)}
        filtered_data = {k: v for k, v in data.items() if k in allowed_keys}
        return cls(**filtered_data)

# 直接用类方法初始化,无需手动过滤
api_response = {'important1': 100, 'important2': 'foo', 'XYZ': '无用字段'}
ci = MyAttrsClass.from_dict(api_response)

这两种方法的优势是:后续类中增减字段时,过滤逻辑会自动适配,不用手动修改键列表,完全基于attrs的元数据实现,比手动删键更灵活可靠。


内容的提问来源于stack exchange,提问作者Wör Du Schnaffzig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:07:30