Python 3.7:dataclass不会针对“ eq = False”引发“ TypeError”

时间:2018-06-29 13:21:30

标签: python python-3.7 python-dataclasses

我正在尝试使用Python 3.7中的新dataclasses

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。相反,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

2 个答案:

答案 0 :(得分:27)

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

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

Number(1) == Number(1)的预期结果是False。这是正确的,因为设置eq = True仅覆盖the default python-object equality function,在这种情况下,该设置仅检查相同的引用(与is相同)。


dataclass specification这里有点缺乏。它用{p>解释了eq参数

  

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

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

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

答案 1 :(得分:6)

当您不定义__eq__时,__eq__将解析为object.__eq__。用eq=False创建数据类时就是这种情况。

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