我正在尝试使用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
其他参数(例如:order
,repr
)的行为似乎符合预期
@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
答案 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
,即除非两者是同一对象。