如何从含多余键值对的字典实例化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
相关产品推荐
相关产品推荐

