inserire la class corrente come annotazione del tipo di ritorno

In python 3 posso creare argomenti e restituire annotazioni di tipo. Esempio:

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 

Il problema è che non riesco a creare un’annotazione con il tipo restituito della class corrente (Graph), che non è ancora stato definito. Esempio:

 class Graph: def reverse(self) -> Graph: pass 

Questo codice va con errore

 def reverse(self) -> Graph: NameError: name 'Graph' is not defined 

Queste annotazioni sono davvero utili sia per documentare che per consentire a IDE di riconoscere argomenti e tipi di ritorno => abilitare il completamento automatico

UPD: Quindi quello che è venuto fuori è che è imansible o richiede alcuni hack che non mi piacciono, quindi ho deciso di usare solo def reverse (self) -> 'Graph': che è comprensibile per la documentazione anche se infrange la regola. Lo svantaggio è che non funziona per il completamento automatico IDE.

Così ora dopo un po ‘posso dire che la decisione che ho preso era usare -> 'Graph' invece di -> Graph . Non rende il mio IDE (PyCharm) in grado di riconoscere un tipo in questo modo ma funziona abbastanza bene per scopi di documentazione.

Un’altra ansible soluzione che potevo utilizzare era la modifica dell’annotazione in fase di esecuzione ma che non risolve il problema con la documentazione: non vorrai cercare dichiarazioni di tipo da qualche parte nel mezzo delle fonti …

Il problema ha radici nel riconoscere l’object di class prima che la class fosse effettivamente definita. Questo è semplicemente imansible da fare in Python.

In python-3.7 questo problema è stato risolto non valutando le annotazioni al momento della definizione della funzione. Invece, sono conservati in __annotations__ in forma di stringa. Questa è chiamata Valutazione posticipata delle annotazioni , introdotta in PEP 563 .

Nota anche:

Politica di deprecazione

A partire da Python 3.7, è necessaria un’importazione __future__ per utilizzare la funzionalità descritta. Nessun avviso viene generato.

In Python 3.8 un PendingDeprecationWarning viene generato dal compilatore in presenza di annotazioni di tipo nei moduli senza l’importazione __future__ .

A partire da Python 3.9 l’avviso diventa DeprecationWarning .

In Python 4.0 questo diventerà il comportamento predefinito. L’uso di annotazioni incompatibili con questo PEP non è più supportato.

Ecco un esempio:

 In [7]: from __future__ import annotations In [8]: class C: ...: def func(cls, arg:str) -> C: ...: pass ...: In [9]: c = C()