Dans python 3 je peux faire des arguments et retourner des annotations de type. Exemple:
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
Le problème est que je ne peux pas faire d'annotation avec le type de retour de la classe actuelle (Graph), qui n'est pas encore définie. Exemple:
class Graph:
def reverse(self) -> Graph:
pass
Ce code s'accompagne d'une erreur
def reverse(self) -> Graph:
NameError: name 'Graph' is not defined
Ces annotations sont vraiment utiles à la fois pour documenter et permettre à IDE de reconnaître les types d'argument et de retour => activer la saisie semi-automatique
UPD: Donc, ce que j'ai trouvé, c'est que c'est impossible ou nécessite des hacks que je n'aime pas, j'ai donc décidé d'utiliser juste def reverse (self) -> 'Graph':
ce qui est compréhensible pour la documentation bien qu'il enfreigne la règle. L'inconvénient est que cela ne fonctionne pas pour IDE saisie semi-automatique.
Alors maintenant, après un certain temps, je peux dire que la décision que j'ai prise utilisait -> 'Graph'
au lieu de -> Graph
. Cela ne rend pas mon IDE (PyCharm) capable de reconnaître un type de cette façon, mais cela fonctionne juste assez bien à des fins de documentation.
Une autre solution possible que je pouvais utiliser était de changer les annotations au moment de l'exécution, mais cela ne résout pas le problème avec la documentation - vous ne voudrez pas chercher des déclarations de type quelque part au milieu des sources ...
Le problème a ses racines dans la reconnaissance des objets de classe avant que la classe ne soit réellement définie. C'est tout simplement impossible à faire en python.
En python-3.7, ce problème a été résolu en n'évaluant pas les annotations au moment de la définition de la fonction. Au lieu de cela, ils sont conservés dans __annotations__
sous forme de chaîne. Cela s'appelle Évaluation différée des annotations, introduit dans PEP 56 .
Notez également:
Politique de dépréciation
Commençant par Python 3.7, un
__future__
l'importation est requise pour utiliser la fonctionnalité décrite. Aucun avertissement n'est émis.Dans Python 3.8 un
PendingDeprecationWarning
est levé par le compilateur en présence d'annotations de type dans les modules sans__future__
import.À partir de Python 3.9, l'avertissement devient un
DeprecationWarning
.Dans Python 4.0, cela deviendra le comportement par défaut. L'utilisation d'annotations incompatibles avec ce PEP n'est plus prise en charge.
Voici un exemple:
In [7]: from __future__ import annotations
In [8]: class C:
...: def func(cls, arg:str) -> C:
...: pass
...:
In [9]: c = C()