如何实现当字段值为None时不更新Device类的属性?
解决WebSocket数据更新时仅保留非None字段的问题
你的核心问题是每次调用update_from_dict时都会重新创建Info实例,导致未传入的字段被覆盖为None。以下是修改后的代码,实现仅更新非None值的需求:
修改后的完整代码
Info 类(添加增量更新方法)
from dataclasses import dataclass, fields @dataclass class Info: ssdp: str ip: str @staticmethod def from_dict(data): # 初始化时按数据创建实例,注意键名与示例数据统一为小写 return Info( ssdp=data.get('ssdp'), ip=data.get('ip'), ) def update_from_dict(self, data): # 遍历dataclass的所有字段,仅更新非None的字段 for field in fields(self): field_value = data.get(field.name) if field_value is not None: setattr(self, field.name, field_value) return self
Device 类(修改更新逻辑)
class Device: def __init__(self, data): # 初始化时直接创建Info实例 self.info = Info.from_dict(data) def update_from_dict(self, data): # 对现有Info实例执行增量更新,而非重新创建 self.info.update_from_dict(data) return self
关键修改说明
Info类新增
update_from_dict方法:- 利用
dataclasses.fields遍历自身所有字段,无需手动维护字段列表,后续扩展字段时无需修改此方法。 - 仅当新数据中对应字段的值不为
None时,才通过setattr更新实例属性,保留原有值。
- 利用
Device类修改更新逻辑:
- 初始化时直接创建
Info实例,不再先设为None。 - 更新时调用现有
info实例的update_from_dict方法,避免重新创建实例导致未传入字段被覆盖为None。
- 初始化时直接创建
修正键名匹配问题:
- 原代码中
Info.from_dict使用了data.get('SSDP'),但示例数据的键是小写ssdp,统一为小写后避免初始化时字段值为None的问题。
- 原代码中
测试结果
- 第一次接收数据后:
{'info': Info(ssdp='foo', ip='bar')} - 第二次接收数据后:
未传入的{'info': Info(ssdp='foo', ip='bar')}ip字段保留了原有值,不会被设为None。
内容的提问来源于stack exchange,提问作者K20GH
相关产品推荐
相关产品推荐

