web-dev-qa-db-ja.com

型注釈で名前が定義されていません

私は現在、python線形代数モジュールを作成して、楽しさと言語の練習のために取り組んでいます。最近、次のように、モジュールに型注釈を追加しようとしました:

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: Vector) -> Vector:
        # More implementation details....

ただし、これをインポートしようとすると、NameError: Name 'Vector' is not defined。この質問には既に here という形式で回答済みであることを認めますが、私の状況に対する回答は完全には提供されていないようです。

私が知りたいこと:

  • このファイルで文字通りクラスを定義しました。名前が定義されていないと表示されるのはなぜですか?
  • Vectorとして)注釈に使用できるようにtypeを定義するにはどうすればよいですか?
35
MutantOctopus

前方宣言があります。 (メソッドとしてバインドされる)関数がbeforeの前に作成されるため、Vectorという名前はまだ存在しません。すべてのクラス本体が実行された場合のみ、Python classオブジェクトを作成し、名前Vectorをそれにバインドできます。

代わりに名前の文字列を使用するだけです。

class Vector:
     # Various irrelevant implementation details
     def __add__(self, other: 'Vector') -> 'Vector':
        # More implementation details....

これは、IDEが宣言を参照する方法には影響しません。モジュール全体がロードされると文字列が検索され、有効なPythonの式として解決されます現在のコンテキスト。モジュール全体が読み込まれると、クラスVectorが存在するため、文字列'Vector'は適切にクラスオブジェクトに変換できます。

前方参照の仕様 も参照してください。

タイプヒントにまだ定義されていない名前が含まれている場合、その定義は文字列リテラルとして表現され、後で解決される場合があります。

[...]

文字列リテラルには有効なPython式[...]が含まれている必要があり、モジュールが完全に読み込まれるとエラーなしで評価されるはずです。

43
Martijn Pieters

Python 3.7以降を使用している場合。 注釈の延期された評価 を見てください

Python 3.7なので、許可されます。追加するだけです:

from __future__ import annotations

そしてまた、

Python 4.0ではデフォルトになります。

18
vishes_shell