简体   繁体   English

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

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

I was trying out the new dataclasses in Python 3.7我正在尝试 Python 3.7 中的新dataclasses

The dataclass decorator can be passed arguments to control the dunder functions that are added to the class.可以向dataclass装饰器传递参数来控制添加到类中的 dunder 函数。

For some reason, the decorator does not seem to raise TypeError for eq=False argument.出于某种原因,装饰器似乎没有为eq=False参数引发TypeError

As per the docs:根据文档:

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

If I understand correctly, if i pass eq = False , __eq__ function will not be added, and a TypeError should be thrown when comparing two instances of the same class.如果我理解正确,如果我通过eq = False ,则不会添加__eq__函数,并且在比较同一类的两个实例时应该抛出TypeError Instead, the eq parameter seems to have no effect.相反, eq参数似乎没有效果。

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

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

a == b
False

a == c
False

The above does not raise TypeError and always evaluates to 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

The other arguments(eg: order , repr ) seem to behave as expected其他参数(例如: 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' 

Is there some gap in my understanding?我的理解有什么差距吗?

I am using docker image python/rc-stretch我正在使用 docker image python/rc-stretch

In python3.7, given the following dataclass definition在python3.7中,给出如下数据类定义

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

the expected result for Number(1) == Number(1) is False . Number(1) == Number(1)的预期结果是False This is correct since setting eq = True only overrides the default python-object equality function , which just checks for identical references (same as Number(1) is Number(1) , which might more obviously evaluate to false ) in this case.这是正确的,因为设置eq = True只覆盖默认的 python-object 相等函数,它只检查相同的引用(与Number(1) is Number(1)相同, Number(1) is Number(1) ,在这种情况下可能更明显地评估为false )。


The dataclass specification is a bit lacking here.这里有点缺乏数据类规范 It explains the eq parameter with它解释了eq参数

eq: If true (the default), an __eq__ method will be generated. eq:如果为 true(默认值),将生成一个 __eq__ 方法。 This method compares the class as if it were a tuple of its fields, in order.此方法按顺序将类作为其字段的元组进行比较。 [...] [...]

but in order to understand the issue you ran into, you also need to know that the basic python object already comes with an __eq__ function:但是为了理解你遇到的问题,你还需要知道基本的python对象已经带有一个__eq__函数:

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

When you don't define __eq__ , __eq__ will resolve to object.__eq__ .当您不定义__eq____eq__将解析为object.__eq__ That is what's happening when you create a dataclass with eq=False .当您使用eq=False创建数据类时,就会发生这种情况。

object.__eq__(self, other) is False unless self is other , ie unless the two are the same object. object.__eq__(self, other)是 False 除非self is other ,即除非两者是同一个对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM