PythonでクラスC内の型ヒントにC自身を指定するとNameErrorが発生する問題の対処法

問題

以下のようにあるクラスCのメソッドfの型ヒントにC自身を使いたいとします。

class C:
    def f(self) -> C:  # causes NameError!
        return C()

このコードをそのまま実行すると以下のようにNameErrorが発生します。

$ python foo.py
Traceback (most recent call last):
  File "/Users/mickey/foo.py", line 1, in <module>
    class C:
  File "/Users/mickey/foo.py", line 2, in C
    def f(self) -> C:
NameError: name 'C' is not defined

原因

メソッドfが定義される時点でクラスC自体の定義が完了していないため、この時点で型名Cを解決できないことがNameErrorの原因です。

解決策

以下のように型ヒントのCをクォートで括ると解決します。

class C:
    def f(self) -> 'C':  # quoted, causes no error
        return C()

これはForward Referencesと呼ばれるもので、型名を文字列リテラルで指定することで型名の解決を後回しにすることができます。

参考資料