web-dev-qa-db-ja.com

現在のクラスを戻り値の注釈として配置する

python 3引数を作成して型注釈を返すことができます。例:

_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
_

問題は、現在定義されていない現在のクラス(グラフ)の戻り値の型で注釈を作成できないことです。例:

_class Graph:
   def reverse(self) -> Graph:
       pass
_

このコードはエラーになります

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

これらの注釈は、文書化とIDEが引数を認識し、型を返すことを許可する両方の場合に非常に役立ちます=>オートコンプリートを有効にします

UPD:私が思いついたのは、これが不可能か、嫌いなハックが必要なことです。そのため、ルールには違反しますが、ドキュメントには理解できるdef reverse (self) -> 'Graph':のみを使用することにしました。欠点は、IDEオートコンプリートでは機能しないことです。

84
sasha.sochka

だから今しばらくして、私は-> 'Graph' の代わりに -> Graph。私のIDE(PyCharm)がこの方法で型を認識できるようにするわけではありませんが、文書化の目的には十分に機能します。

私が使用できる別の可能な解決策は、実行時に注釈を変更することでしたが、ドキュメントの問題を解決しません-ソースの途中で型宣言を探したくないでしょう...

この問題は、クラスが実際に定義される前にクラスオブジェクトを認識することに原因があります。 Pythonでそれを行うことは不可能です。

54
sasha.sochka

Python-3.7では、関数定義時に注釈を評価しないことでこの問題は解決されました。代わりに、__annotations__に文字列形式で保存されます。これは、注釈の延期された評価と呼ばれ、 PEP 56 で導入されました。

また注意してください:

廃止ポリシー

Python 3.7)以降、説明した機能を使用するには__future__インポートが必要です。警告は発生しません。

Python 3.8 a PendingDeprecationWarningは、__future__インポートのないモジュール内の型注釈の存在下でコンパイラによって発生します。

Python 3.9で始まる警告はDeprecationWarningになります。

Python 4.0ではこれがデフォルトの動作になります。このPEPと互換性のないアノテーションの使用はサポートされなくなりました。

次に例を示します。

In [7]: from __future__ import annotations

In [8]: class C:
   ...:     def func(cls, arg:str) -> C:
   ...:         pass
   ...:     

In [9]: c = C()
31
Kasrâmvd