python 3.7 dataclasses
Python 3.7: dataclass no genera `TypeError` para` eq=False` (2)
Cuando no defina __eq__
, __eq__
se resolverá a object.__eq__
. Eso es lo que sucede cuando crea una clase de datos con eq=False
.
object.__eq__(self, other)
es False a menos que self is other
, es decir, a menos que los dos sean el mismo objeto.
Estaba probando las nuevas dataclasses
de dataclasses
en Python 3.7.
Al decorador de dataclass
se le pueden pasar argumentos para controlar las funciones de dunder que se agregan a la clase.
Por alguna razón, el decorador no parece elevar TypeError
para el argumento eq=False
.
Según los documentos:
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
Si entiendo correctamente, si paso eq = False
, la función __eq__
no se agregará, y se debe lanzar un TypeError
cuando se comparan dos instancias de la misma clase. En cambio, el parámetro eq
parece no tener efecto.
@dataclass(eq = False)
class Number:
val: int
a = Number(1)
b = Number(2)
c = Number(1)
a == b
False
a == c
False
Lo anterior no TypeError
y siempre se evalúa como 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
Los otros argumentos (p. Ej., order
, repr
) parecen comportarse como se espera
@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''
¿Hay algún vacío en mi comprensión?
Estoy usando la imagen docker python/rc-stretch
En python3.7, dada la siguiente definición de clase de datos
@dataclass(eq=False)
class Number:
val: int
el resultado esperado para el Number(1) == Number(1)
es False
. Esto es correcto ya que la configuración de eq = True
solo invalida la función de igualdad de objetos / pitones predeterminada , que solo busca referencias idénticas (lo mismo que en el caso) en este caso.
La especificación de la clase de datos es un poco escasa aquí. Explica el parámetro eq
con
eq: Si es verdadero (el valor predeterminado), se generará un método __eq__. Este método compara la clase como si fuera una tupla de sus campos, en orden. [...]
pero para comprender el problema con el que se encontró, también necesita saber que el objeto Python básico ya ofrece una función __eq__
:
>>> class A: pass
...
>>> dir(A())
[''__class__'', ''__delattr__'', ... ''__eq__'', ...] # has __eq__ already