python の型ヒント(アノテーション)については、基本的に 公式ドキュメント に記述されている。しかし、実用的な範囲でのシンプルな例が記載されているため、理解したいこと以外の情報もあり、やや理解しにくいことがある。そのため今回、実用性は度外視し、 TypeVar 自体を理解することだけを目的とした情報を残したく、本記事を作成した。なお、記事中の表現は、筆者独自の表現である場合があることはご了承いただきたい。
python のバージョンは 3.9 を想定している。
TypeVar とは
TypeVar とは、「とある決まった型」を表す場合に用いる型変数である。
TypeVar の使用例
例えば下記のように、引数をそのまま返す関数の定義に使用する。
from typing import TypeVar
T = TypeVar("T")
def get_t_arg(arg: T) -> T:
return arg
上記の get_t_arg(arg: T) -> T の型ヒントは、 「引数 arg の型が T であるとき、返り値の型が T である」 ことを意味する。例えば、 get_t_arg の引数として渡した arg の型が int であるときの返り値の型は int であるし、 arg の型が str であるときの返り値の型は str である。
TypeVar と Any の違い
Any とは、制約のない型である。
下記例を用いて TypeVar との違いの説明を試みる。
from typing import Any
def get_any_arg(arg: Any) -> Any:
return arg
上記の get_any_arg(arg: Any) -> Any の型ヒントは、 「引数 arg に型の制約はなく、返り値にも型の制約はない」 ことを意味する。例えば、 get_any_arg の引数として渡した arg の型が int であるときの返り値の型に制約はなく、返り値の型が int や str などの可能性がある(当然 get_any_arg の実装上、引数と返り値の型が異なることはないが、型ヒントが表すのはそのような意味となる)。
このように、 TypeVar と Any は全く異なる。
許容する型を制限する場合の TypeVar の使用例
TypeVar を用いたいが、許容する型を制限したい場合がある(例えば「 int または float のみを許容する」など)。その際の使用例は下記。
from typing import TypeVar
T = TypeVar("T", int, float)
def add_one_to_t_arg(arg: T) -> T:
return arg + 1
上記のように T = TypeVar("T", int, float) と宣言した際の add_one_to_t_arg(arg: T) -> T の型ヒントは、 「引数 arg の型は int または float であり、 arg の型が int のときの返り値の型は int、 arg の型が float のときの返り値の型は float である」 ことを意味する。
許容する型を制限する場合の TypeVar と Union の違い
Union とは、「指定したいずれかの型」を表す型である。
下記例を用いて TypeVar との違いの説明を試みる。
from typing import Union
def add_one_to_num(num: Union[int, float]) -> Union[int, float]:
return num + 1
上記の add_one_to_num(num: Union[int, float]) -> Union[int, float] の型ヒントは、 「引数 num の型は int または float であり、返り値の型も int または float である」 ことを意味する。例えば、 add_one_to_num の引数として渡した num の型が int であるとき、返り値の型は int である可能性も float である可能性もある。
複数の TypeVar を使用する例
from typing import TypeVar
T = TypeVar("T")
S = TypeVar("S")
def get_t_and_s_args(t_arg: T, s_arg: S) -> tuple[T, S]:
return t_arg, s_arg
上記の get_t_and_s_args(t_arg: T, s_arg: S) -> tuple[T, S] の型ヒントは、 「第一引数 t_arg の型が T、第二引数 s_arg の方が S のとき、返り値の方は tuple[T, S] である」 ことを意味する。
以上です。閲覧ありがとうございました!