Self 型は Python 3.11 で導入され、メソッドが自身のクラス型を返すことを正確に表現できます。継承時にも正しい型が推論されます。
問題の背景
従来、自身を返すメソッドの型付けは面倒でした。
from typing import TypeVar T = TypeVar("T", bound="Builder") class Builder: def set_name(self: T, name: str) -> T: self.name = name return self
クラスごとに TypeVar を定義する必要がありました。
Self 型の基本
from typing import Self class Builder: def set_name(self, name: str) -> Self: self.name = name return self def set_value(self, value: int) -> Self: self.value = value return self
Self は「このメソッドを呼び出したインスタンスの型」を意味します。
継承での動作
from typing import Self class Animal: def set_name(self, name: str) -> Self: self.name = name return self class Dog(Animal): def set_breed(self, breed: str) -> Self: self.breed = breed return self dog = Dog().set_name("Buddy").set_breed("Labrador") # dog の型は Dog
Animal.set_name の返り値は Dog として推論されます。TypeVar を使った場合と同じ効果ですが、より簡潔です。
ファクトリメソッド
from typing import Self class Config: def __init__(self, data: dict): self.data = data @classmethod def from_file(cls, path: str) -> Self: with open(path) as f: return cls(json.load(f)) class AppConfig(Config): pass config = AppConfig.from_file("config.json") # config の型は AppConfig
再帰的な型定義
from typing import Self class Node: def __init__(self, value: int): self.value = value self.children: list[Self] = [] def add_child(self, child: Self) -> Self: self.children.append(child) return self
Self 型により、メソッドチェーンやファクトリパターンの型付けが簡潔かつ正確になります。