python - Usar la clase como una sugerencia de tipo para argumentos en sus métodos
python-3.x oop (2)
El código que he incluido a continuación arroja el siguiente error:
NameError: name ''Vector2'' is not defined
en esta linea:
def Translate (self, pos: Vector2):
¿Por qué Python no reconoce mi clase
Vector2
en el método
Translate
?
class Vector2:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def Translate(self, pos: Vector2):
self.x += pos.x
self.y += pos.y
La característica que está solicitando se llama referencias hacia adelante (tipo), y se ha agregado a Python a partir de 3.7 (en PEP 563 ). 1 Así que esto ahora es válido:
from __future__ import annotations
class C:
def spam(self, other: C) -> C:
pass
Observe la
declaración
__future__
.
Esto será necesario
hasta 4.0
.
Desafortunadamente, en Python 3.6 y versiones anteriores, esta característica no está disponible, por lo que debe usar anotaciones de cadena, como se explica en la respuesta de Jim Fasarakis Hilliard .
Mypy ya admite declaraciones directas, incluso cuando se ejecuta en Python 3.6, pero no le sirve de mucho si el verificador de tipo estático dice que su código está bien, pero el intérprete genera un
NameError
cuando intenta ejecutarlo realmente.
1. Esto ya se discutió como una posible característica en PEP 484 , pero se aplazó hasta más tarde, después de que las personas tuvieran más experiencia en el uso de declaraciones directas en anotaciones. PEP 563 / Python 3.7 es ese "posterior".
Porque cuando encuentra
Translate
(mientras compila el cuerpo de la clase),
Vector2
aún no se ha definido (actualmente se está compilando, no se ha realizado el enlace de nombre);
Python se queja naturalmente.
Dado que este es un escenario tan común (insinúa una clase en el cuerpo de esa clase), debe usar una referencia hacia adelante encerrándola entre comillas:
class Vector2:
# __init__ as defined
def Translate(self, pos: ''Vector2''):
self.x += pos.x
self.y += pos.y
Python (y cualquier corrector que cumpla con
PEP 484
) comprenderá su sugerencia y la registrará adecuadamente.
Python reconoce esto cuando se accede a
typing.get_type_hints
través de
typing.get_type_hints
:
from typing import get_type_hints
get_type_hints(Vector2(1,2).Translate)
{''pos'': __main__.Vector2}
Esto se ha cambiado a partir de Python 3.7; ver la respuesta de abarnert a continuación .