class - reflexion - poner la clase actual como anotación de tipo de retorno
reflection en java (2)
En python-3.7, este problema se ha resuelto al no evaluar las anotaciones en el momento de la definición de la función. En cambio, se conservan en __annotations__
en forma de cadena. Esto se denomina Evaluación de anotaciones pospuesta , introducido en PEP 563 .
También tenga en cuenta:
Política de depreciación
Comenzando con Python 3.7, se requiere una importación
__future__
para usar la funcionalidad descrita. No se generan advertencias.En Python 3.8, el compilador
PendingDeprecationWarning
unaPendingDeprecationWarning
en presencia de anotaciones de tipo en los módulos sin la importación__future__
.Comenzando con Python 3.9, la advertencia se convierte en una advertencia de
DeprecationWarning
.En Python 4.0 esto se convertirá en el comportamiento predeterminado. El uso de anotaciones incompatibles con este PEP ya no es compatible.
Aquí hay un ejemplo:
In [7]: from __future__ import annotations
In [8]: class C:
...: def func(cls, arg:str) -> C:
...: pass
...:
In [9]: c = C()
En python 3 puedo hacer argumentos y devolver anotaciones tipo. Ejemplo:
class Graph:
def __init__(self, V: int, E: int, edges: list):
pass
@classmethod
def fromfile(cls, readobj: type(sys.stdin)):
pass
def V(self) -> int:
pass
def E(self) -> int:
pass
El problema es que no puedo hacer una anotación con el tipo de devolución de la clase actual (Gráfico), que aún no está definido. Ejemplo:
class Graph:
def reverse(self) -> Graph:
pass
Este código va con error
def reverse(self) -> Graph:
NameError: name ''Graph'' is not defined
Estas anotaciones son realmente útiles tanto para documentar como para permitir que IDE reconozca argumentos y devolver tipos => habilitar autocompletar
UPD: Entonces, lo que surgió es que esto es imposible o requiere algunos hacks que no me gustan, así que decidí usar simplemente def reverse (self) -> ''Graph'':
que es comprensible para la documentación aunque rompe la regla. La desventaja es que no funciona para autocompletar IDE.
Entonces, después de un tiempo, puedo decir que la decisión que tomé fue usar -> ''Graph''
lugar de -> Graph
. No hace que mi IDE (PyCharm) pueda reconocer un tipo de esta manera, pero funciona lo suficientemente bien para fines de documentación.
Otra posible solución que podría usar fue cambiar la anotación en tiempo de ejecución, pero eso no soluciona el problema con la documentación: no querrá buscar declaraciones de tipo en algún lugar en el medio de las fuentes ...
El problema tiene sus raíces en el reconocimiento de objeto de clase antes de que la clase realmente se haya definido. Eso es simplemente imposible de hacer en Python.