PEP 563 では、from __future__ import annotations
型注釈が遅延評価されるように変更されます。これにより、前方参照などの多くの利点が得られます。
ただし、これはデータクラスなどの他の機能とうまく機能しないようです。たとえば、クラスの__init__
メソッドの型パラメーターを検査するコードがあります。(実際の使用例は、クラスにデフォルトのシリアライザーを提供することですが、ここでは重要ではありません。)
from dataclasses import dataclass
from typing import get_type_hints
class Foo:
pass
@dataclass
class Bar:
foo: Foo
print(get_type_hints(Bar.__init__))
Python 3.6 および 3.7 では、これは期待どおりの動作をします。それは印刷し{'foo': <class '__main__.Foo'>, 'return': <class 'NoneType'>}
ます。
ただし、Python 3.7 で を追加するfrom __future__ import annotations
と、次のエラーで失敗します。
NameError: name 'Foo' is not defined
なぜこれが起こっているのか理解できたと思います。__init__
メソッドは で定義されており、その環境にdataclasses
はオブジェクトがなく、注釈は元のオブジェクトとしてではなく文字列として渡され、添付されていますが、新しい注釈の場合は、モジュール内で名前のルックアップのみを行います。注釈が定義されている場所では定義されていません。Foo
Foo
dataclass
__init__
"Foo"
Foo
get_type_hints
__init__
何か間違ったことをしているに違いないような気がします。これら 2 つの新機能の連携がうまくいかないことに驚いています。メソッドの型ヒントを調べて、__init__
通常のクラスと同じようにデータクラスで機能する適切な方法はありますか?