如何在初始化dataclass对象时忽略值为None的未指定属性?
解决Dataclass实例仅保留传入属性的简洁方法
你用Python dataclass定义了如下父类与子类:
from dataclasses import dataclass @dataclass class TestMain: one_test: int = None two_test: int = None @dataclass class SecondTest(TestMain): three_test: int = None four_test: int = None
当用仅包含部分属性的字典创建SecondTest实例时:
test_data = {'one_test': 1, 'two_test': 2, 'three_test': 3} test_object = SecondTest(**test_data)
未指定的four_test会被设为None并保留在实例中,但你希望实例完全不包含这些未传入的属性,且觉得用asdict配合过滤工厂函数的方式过于冗余:
dict_object = asdict(test_object, dict_factory=lambda x: {k: v for (k, v) in x if v is not None})
以下是几种更简洁的实现方式:
方法1:自定义初始化方法
通过禁用dataclass自动生成的__init__,手动实现只初始化传入属性的逻辑,同时兼容父类字段:
from dataclasses import dataclass, fields @dataclass class TestMain: one_test: int = None two_test: int = None @dataclass(init=False) class SecondTest(TestMain): three_test: int = None four_test: int = None def __init__(self, **kwargs): # 收集当前类及所有父类的字段名集合 all_field_names = {field.name for field in fields(self)} # 仅为传入且属于类字段的属性赋值 for key, value in kwargs.items(): if key in all_field_names: setattr(self, key, value)
使用该方式创建实例后,未传入的属性不会被初始化,自然不存在于实例中:
test_object = SecondTest(**test_data) print(hasattr(test_object, 'four_test')) # 输出 False
方法2:初始化后删除None值属性
若不想完全重写初始化逻辑,可利用__post_init__钩子删除值为None的属性:
from dataclasses import dataclass, fields @dataclass class TestMain: one_test: int = None two_test: int = None @dataclass class SecondTest(TestMain): three_test: int = None four_test: int = None def __post_init__(self): # 遍历所有字段,删除值为None的属性 for field in fields(self): attr_value = getattr(self, field.name) if attr_value is None: delattr(self, field.name)
创建实例的方式不变,初始化完成后four_test会被自动删除:
test_object = SecondTest(**test_data) print(hasattr(test_object, 'four_test')) # 输出 False
方法3:封装简洁的字典转换函数
如果你的核心需求只是将实例转换为过滤掉None值的字典,可封装一个复用函数替代冗长的lambda写法:
from dataclasses import asdict, dataclass def clean_dataclass_dict(obj): return {key: val for key, val in asdict(obj).items() if val is not None} # 调用示例 dict_object = clean_dataclass_dict(test_object)
内容的提问来源于stack exchange,提问作者KarimovAnton
相关产品推荐
相关产品推荐

