Python の TypeVar とジェネリクス
TypeVar を使うと、ジェネリックな関数や型を定義できます。入力と出力の型の関係を保ちながら、さまざまな型に対応する関数を作れます。
基本的な使い方
TypeVar で型変数を定義し、関数の引数と戻り値で同じ型を表現します。
from typing import TypeVar
T = TypeVar("T")
def identity(x: T) -> T:
return x
result1 = identity(42) # int を受け取り int を返す
result2 = identity("hello") # str を受け取り str を返す
型チェッカーは、引数の型から戻り値の型を推論します。
型の制約
bound を指定すると、その型またはサブクラスに制限できます。
from typing import TypeVar
class Animal:
def speak(self) -> str:
return "..."
class Dog(Animal):
def speak(self) -> str:
return "Woof!"
T = TypeVar("T", bound=Animal)
def make_speak(animal: T) -> T:
print(animal.speak())
return animal
特定の型のみ許可
複数の型を列挙して制限することもできます。
from typing import TypeVar
T = TypeVar("T", int, float)
def double(x: T) -> T:
return x * 2 # type: ignore
double(5) # OK
double(3.14) # OK
double("a") # 型エラー
リストのジェネリクス
コンテナ型と組み合わせると、要素の型を保持できます。
from typing import TypeVar, List
T = TypeVar("T")
def first(items: List[T]) -> T:
return items[0]
x = first([1, 2, 3]) # int
y = first(["a", "b"]) # str
TypeVar を活用すると、汎用的でありながら型安全なコードを書けます。