この記事では以下について記載しています。
- 特殊メソッドについて
- 型ヒント用のパッケージ輸入
from __future__ import annotationsfrom typing import TYPE_CHECKING
概要
from monai.transforms import LoadImaged, ...
def train_transform(config) -> Transform:
transforms = Compose(
[ LoadImaged(...), ...]
)
->
# NameError: name 'Transform' is not defined
画像の前処理を実装していた際、上記のようなエラーにあたりました。
これを回避するため以下を追加したのですが、
from monai.transforms import Transform
これって、
使用する前処理に関わるクラスだけを輸入して、不要な処理を避けていたのに、実行に関わらないマナーのような型ヒントのために処理時間を増やしてまでサブモジュール(場合によってはパッケージ)を輸入するのはどうなんだという考えです。
解決方法
from __future__ import annotations
from typing import TYPE_CHECKING
とりあえずファイルの一番上に書いとけば、型ヒントのために不要な処理を行う必要は無くなります。
from __future__ import annotations
from typing import TYPE_CHECKING
from monai.transforms import LoadImaged, ...
def train_transform(config) -> Transform:
transforms = Compose(
[ LoadImaged(...), ...]
)
->
# clear
ですが、mypyでチェックを行う場合、定義されていないオブジェクトは引っかかってしまいます。
その場合は、
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from monai.transforms import Transform
以下では、
from __future__ import annotations-
from typing import TYPE_CHECKING
について解説します。
特殊メソッド
__xxx__ のようにダブルアンダースコアで囲まれたメソッドの総称。Pythonの言語機能に触れるため、組み込み関数などと同じ振る舞いを持たせられます。
組み込み演算の中身
演算子や組み込み関数は、内部で対応する特殊メソッドが機能をもっています。
例)
a + b # → a.__add__(b)
len(a) # → a.__len__()
str(a) # → a.__str__()
from __future__ import annotations
__future__ は将来実装予定のパッケージなどを先行導入するための特殊メソッドです。annotations をインポートすると、型ヒントの評価から除外され、すべて文字列として扱われます。
以下のような場面で役にたちます。
from __future__ import annotations
class User:
def copy(self) -> User: # 本来Userは未定義
...
未定義となっているUserのチェックを遅らせ、文字列として扱うことでエラーを避けて型チェックを入れる事が出来ます。
from typing import TYPE_CHECKING
静的型チェッカー(mypy, Pyright 等)実行時のみ True になります。if TYPE_CHECKING: ブロック内のインポートは、型チェック時のみTrue、実行時はFalseとなり実行されません。
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .post import Post # 実行時はインポートされない
def get_post(id: int) -> Post:
...
まとめ
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .post import Post
def get_post() -> Post:
...
| タイミング | 動作 |
|---|---|
| 静的型チェック時 |
TYPE_CHECKING=True → Post がインポートされ、補完・定義ジャンプが有効 |
| 実行時 |
TYPE_CHECKING=False → インポートされない。annotations により文字列のまま保持されエラーを避ける |