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

如何实现当字段值为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

关键修改说明

  1. Info类新增update_from_dict方法:

    • 利用dataclasses.fields遍历自身所有字段,无需手动维护字段列表,后续扩展字段时无需修改此方法。
    • 仅当新数据中对应字段的值不为None时,才通过setattr更新实例属性,保留原有值。
  2. Device类修改更新逻辑:

    • 初始化时直接创建Info实例,不再先设为None。
    • 更新时调用现有info实例的update_from_dict方法,避免重新创建实例导致未传入字段被覆盖为None。
  3. 修正键名匹配问题:

    • 原代码中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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:57:24