python python-3.x oop type-hinting

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 .