dataclasses data classes python python-3.7 python-dataclasses

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