型の自己参照がどのように機能するかを理解しようとしています python3の型注釈 -ドキュメントはこれに関して何も指定していません。
例として:
from typing import TypeVar, Optional, Generic
T = TypeVar('T')
class Node(Generic[T]):
left = None
right = None
value = None
def __init__(
self, value: Optional[T],
left: Optional[Node[T]]=None,
right: Optional[Node[T]]=None,
) -> None:
self.value = value
self.left = left
self.right = right
このコードはエラーを生成します:
Traceback (most recent call last):
File "node.py", line 4, in <module>
class Node(Generic[T]):
File "node.py", line 12, in Node
right: Optional[Node[T]]=None,
NameError: name 'Node' is not defined
これはPython 3.5.1を使用しています
PEP 0484-タイプのヒント-前方宣言の問題 は問題に対処します:
タイプヒントの問題は、注釈( PEP 3107 ごと、デフォルト値と同様)が関数の定義時に評価されることです。したがって、注釈で使用される名前は、関数が定義されています。一般的なシナリオは、メソッドがアノテーションでクラス自体を参照する必要があるクラス定義です。 (より一般的には、相互再帰クラスでも発生する可能性があります。)これは、次のようなコンテナタイプでは自然です。
.。
書かれているように、これは機能しません。Pythonの特殊性のため、クラスの本体全体が実行されると、クラス名が定義されるようになります。私たちの解決策、これは特にエレガントではありませんが、仕事を成し遂げるには、注釈で文字列リテラルを使用できるようにすることです。ほとんどの場合、これを使用する必要はありません-ほとんどのタイプの使用ヒントは、組み込み型または他のモジュールで定義された型を参照することが期待されています。
from typing import TypeVar, Optional, Generic
T = TypeVar('T')
class Node(Generic[T]):
left = None
right = None
value = None
def __init__(
self,
value: Optional[T],
left: Optional['Node[T]']=None,
right: Optional['Node[T]']=None,
) -> None:
self.value = value
self.left = left
self.right = right
>>> import typing
>>> typing.get_type_hints(Node.__init__)
{'return': None,
'value': typing.Union[~T, NoneType],
'left': typing.Union[__main__.Node[~T], NoneType],
'right': typing.Union[__main__.Node[~T], NoneType]}