Python 3.7:数据类不会为 `eq=False` 引发 `TypeError`

Python 3.7: dataclass does not raise `TypeError` for `eq=False`

我正在试用 Python 3.7

中的新 dataclasses

dataclass 装饰器可以传递参数来控制添加到 class 的 dunder 函数。

出于某种原因,装饰器似乎没有为 eq=False 参数引发 TypeError

根据文档:

eq: If true (the default), an __eq__ method will be generated. 
This method compares the class as if it were a tuple of its fields, in order. 
Both instances in the comparison must be of the identical type

如果我理解正确的话,如果我传递eq = False__eq__函数将不会被添加,并且在比较相同[=47的两个实例时应该抛出一个TypeError =].相反,eq 参数似乎没有任何作用。

@dataclass(eq = False)
class Number:
    val: int

a = Number(1)
b = Number(2)
c = Number(1)

a == b
False

a == c
False

以上不会引发 TypeError 并且始终计算为 False.

@dataclass()
class Number:
    val: int

a = Number(1)
b = Number(2)
c = Number(1)

a
Number(val = 1)

a == b
False

a == c
True

其他参数(例如:orderrepr)似乎符合预期

@dataclass(order = False, repr = False)
class Number:
    val:int

a = Number(1)
b = Number(2)
c = Number(1)

a
<__main__.Number object at 0x7fe1036c8b38>

a < b
Traceback (most recent call last):                                                                                                          
  File "<stdin>", line 1, in <module>                                                                                                       
TypeError: '<' not supported between instances of 'Number' and 'Number' 

是不是我的理解有问题?

我正在使用 docker 图片 python/rc-stretch

在python3.7中,给定如下数据类定义

@dataclass(eq=False)
class Number:
    val: int

Number(1) == Number(1) 的预期结果是 False。这是正确的,因为在这种情况下设置 eq = True 仅覆盖 the default python-object equality function,它只检查相同的引用(与 Number(1) is Number(1) 相同,这可能更明显地评估为 false)。


dataclass specification这里有点欠缺。它用

解释了eq参数

eq: If true (the default), an __eq__ method will be generated. This method compares the class as if it were a tuple of its fields, in order. [...]

但是为了理解您 运行 遇到的问题,您还需要知道基本 python 对象已经带有 __eq__ 函数:

>>> class A: pass
...
>>> dir(A())
['__class__', '__delattr__', ... '__eq__', ...]  # has __eq__ already

当您不定义 __eq__ 时,__eq__ 将解析为 object.__eq__。这就是使用 eq=False.

创建数据类时发生的情况

object.__eq__(self, other) 为 False,除非 self is other,即除非两者是同一个对象。