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

为何成员变量值不同的Dataclass对象判定相等?

问题:Dataclass对象比较结果不符合预期

定义了包含3个成员变量的Dataclass类DiagCodes,创建两个成员变量值不同的对象并判断相等时,结果始终为True。代码如下:

from dataclasses import dataclass
from typing import Optional

@dataclass(init=False)
class DiagCodes:
    __slots__ = ["indx_nbr", "diag_cd", "diag_typ_cd"]

    def __init__(
        self,
        indx_nbr: Optional[int] = None,
        diag_cd: Optional[str] = None,
        diag_typ_cd: Optional[str] = None,
    ) -> None:

        self.indx_nbr = indx_nbr
        self.diag_cd = diag_cd
        self.diag_typ_cd = diag_typ_cd

if __name__ == "__main__":
    dc = DiagCodes(1)
    dc_empty = DiagCodes()

    print(dc == dc_empty)  # 输出: True

按照Dataclass的默认__eq__方法实现,结果应该为False才对,使用Python版本为3.8.10。


原因与解决方案

原因

@dataclass装饰器默认会根据类体中带有类型注解的成员变量生成__eq__方法,以此作为对象相等性判断的依据。你的代码存在两个关键问题:

  • 仅通过__slots__声明成员变量,未在类体中显式定义带类型注解的字段;
  • 使用init=False并手动实现__init__,但dataclass无法从__init__参数中自动识别需要纳入比较的字段。

由于dataclass检测不到任何需要比较的字段,生成的__eq__方法会将所有实例视为相等——因为没有字段可以用来区分它们。

解决方案

方式一:在类体中显式定义带类型注解的字段

保留__slots__和手动__init__,在类体中添加字段的类型注解,让dataclass识别需要比较的字段:

from dataclasses import dataclass
from typing import Optional

@dataclass(init=False)
class DiagCodes:
    __slots__ = ["indx_nbr", "diag_cd", "diag_typ_cd"]
    # 显式定义字段类型注解
    indx_nbr: Optional[int]
    diag_cd: Optional[str]
    diag_typ_cd: Optional[str]

    def __init__(
        self,
        indx_nbr: Optional[int] = None,
        diag_cd: Optional[str] = None,
        diag_typ_cd: Optional[str] = None,
    ) -> None:
        self.indx_nbr = indx_nbr
        self.diag_cd = diag_cd
        self.diag_typ_cd = diag_typ_cd

if __name__ == "__main__":
    dc = DiagCodes(1)
    dc_empty = DiagCodes()

    print(dc == dc_empty)  # 输出: False

方式二:手动实现__eq__方法

如果不想依赖dataclass自动生成的__eq__,可以自行实现相等性判断逻辑:

from dataclasses import dataclass
from typing import Optional

@dataclass(init=False)
class DiagCodes:
    __slots__ = ["indx_nbr", "diag_cd", "diag_typ_cd"]

    def __init__(
        self,
        indx_nbr: Optional[int] = None,
        diag_cd: Optional[str] = None,
        diag_typ_cd: Optional[str] = None,
    ) -> None:
        self.indx_nbr = indx_nbr
        self.diag_cd = diag_cd
        self.diag_typ_cd = diag_typ_cd

    def __eq__(self, other):
        if not isinstance(other, DiagCodes):
            return NotImplemented
        return (self.indx_nbr == other.indx_nbr and
                self.diag_cd == other.diag_cd and
                self.diag_typ_cd == other.diag_typ_cd)

if __name__ == "__main__":
    dc = DiagCodes(1)
    dc_empty = DiagCodes()

    print(dc == dc_empty)  # 输出: False

内容的提问来源于stack exchange,提问作者Vandit Goel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:05:57