El siguiente código no funciona como se esperaba. Aparentemente, no puedo usar el tipo propio de las clases dentro de la definición de clase:
class Foo: def __init__(self, key :str) -> None: self.key = key def __eq__(self, other :Foo) -> bool: return self.key == other.key print('should be true: ', Foo('abc') == Foo('abc')) print('should be false: ', Foo('abc') == Foo('def'))El resultado de ejecutarlo es:
Traceback (most recent call last): File "class_own_type.py", line 1, in <module> class Foo: File "class_own_type.py", line 5, in Foo def __eq__(self, other :Foo) -> bool: NameError: name 'Foo' is not defined Además, verificar el código con mypy devuelve:
class_own_type.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object" ¿Cómo puedo corregir este código para que sea válido, tanto para Python como para mypy ?
El nombre Foo aún no está vinculado, porque la clase en sí aún no se ha definido en el momento en que intenta usar el nombre (recuerde: los argumentos de la función se evalúan en el momento de la definición de la función, no en el momento de la llamada de la función).
Desde Python 3.7+, puede posponer la evaluación de las anotaciones agregando esta importación en la parte superior del módulo:
from __future__ import annotationsEn Python 3.10, la evaluación pospuesta se convertirá en el comportamiento predeterminado. Para Python < 3.7, puede usar cadenas literales para retrasar la evaluación del tipo:
class Foo: def __init__(self, key :str) -> None: self.key = key def __eq__(self, other: 'Foo') -> bool: return self.key == other.key print('should be true: ', Foo('abc') == Foo('abc')) print('should be false: ', Foo('abc') == Foo('def'))