Python 3.7で導入された dataclass はかなり広く使われるようになり、Pythonの型チェッカも dataclass
を認識してコーディングミスを防いでくれるようになっています。
ところで、Pythonのサードパーティライブラリには、似たようなインターフェースをもつクラスが多く存在します。たとえば DjangoのModel は次のようにデータベースのスキーマを定義します。
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
見た目は dataclass
とよく似ていますが、DjangoのModelは型チェッカで直接サポートされておらず、型チェックを行うためには専用のスタブやプラグインなどが必要になっています。
そこで、PEP 681 Data Class Transforms では、typing.dataclass_transform を提供し、DjangoのModel定義が dataclass
と同じように動作する、と型チェッカに教えることができるようになりました。
例えば、次の例ではクラス Base
を使って、派生クラス Address
を定義しています。
from typing import dataclass_transform
class Base
pass
class Address(Base):
zip: str
pref: str
この場合、Address
クラスのインスタンスを作成するときに
addr = Address(zip="111", pref="Saitama")
と書くと、型チェッカではエラーとなります。Address
クラスのコンストラクタには引数を指定できないためです。
しかし、次のように Base
クラスを dataclass_transform
でデコレートすると、型チェッカに 「Base
は、dataclass
と同じように特別な仕組みで引数をうけとります」 と指定できます。
from typing import dataclass_transform
@dataclass_transform()
class Base
pass
class Address(Base):
zip: str
pref: str
この指定により、こんどは
addr = Address(zip="111", pref="Saitama")
はエラーとはなりません。
また、
aadr2 = Address(zip="111")
は、属性 pref
が指定されていないのでエラーとなります。同様に、
aadr3 = Address(zip="111", pref="222", street="333")
は、余計な引数 street
が入っているのでエラーとなります。
このように dataclass
と同じような型チェックをサードパーティのクラスでも行えるようになり、将来的にはより多くのライブラリが、もっと簡単に型アノテーションに対応できるようになることが期待できます。