21

我正在尝试dataclassesPython 3.7中的新功能

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

出于某种原因,装饰者似乎没有提出TypeError争论eq=False

根据文档:

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__将不会添加函数,并且TypeError在比较同一类的两个实例时应该抛出 a 。相反,该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' 

我的理解有差距吗?

我正在使用泊坞窗图像python/rc-stretch

4

2 回答 2

28

在python3.7中,给定如下dataclass定义

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

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


这里缺少数据类规范。它解释了eq参数

eq:如果为 true(默认),将生成一个 __eq__ 方法。此方法按顺序比较类,就好像它是其字段的元组一样。[...]

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

>>> class A: pass
...
>>> dir(A())
['__class__', '__delattr__', ... '__eq__', ...]  # has __eq__ already
于 2018-06-29T13:38:16.700 回答
6

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

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

于 2018-06-29T13:46:05.807 回答