2016-03-29 25 views
16

私は現在、楽しいと言語の練習のための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など)に使用できるように定義するにはどうすればよいですか?
+0

投稿を1件につき** 1件の**質問に限定してください。ここでは循環依存(クラスが作成される前のクラスのメソッド)と、タイプとクラスの違いについて2つの異なる質問があります。後者は重複している。 –

+0

[Class vsあなたの投稿から削除した質問の部分については、Pythonを入力](https://stackoverflow.com/q/35958961)を参照してください。 –

+0

申し訳ありません。私はタイプの質問が手元の問題に関連していると思った。 – BHustus

答えて

21

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

単に代わりに名前の文字列を使用します。

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

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

型ヒントがまだ定義されていない名前が含まれ、その定義は、後に解決される、文字列リテラルのように表すことができる。

specification on forward references参照してください。

[...]

文字列リテラルは、[...]有効なPythonの式が含まれている必要があり、モジュールが完全にロードされた後、それはエラーなしで評価する必要があります。

+0

ありがとう。私はリンクされた質問で文字列答えを見ましたが、私を捨てたのはクラスカラーで 'other:Vector'と' - > Vector'を強調表示していたことでした。したがって、後者のベクトルにコメントしたとき、前者のためにそうする必要があった。説明をありがとう。 – BHustus

1

Python 3.7以上を使用している場合は、 Pythonの3.7以来Postponed evaluation of annotations

を見て、それだけで追加し、許可されます。

from __future__ import annotations 

これは、Python 4.0のデフォルトになることに注意してください。

+1

これは興味深いことです。私はすべての3.xバージョン(または少なくとも、 'import annotations'ソリューションよりも3.xバージョン以上)で動作するので、そのまま答えを残すつもりですが、ここに投稿していただきありがとうございます。 – BHustus

関連する問題