Python3.11の新機能 Python 3.11の新機能(その7) 型ヒントの新機能 - PEP-681 データクラス変換

(その1) CPython高速化計画(その2) 特殊化適応的インタープリタ(その3) 関数呼び出しのインライン化(その4) 例外グループとTaskGroup(その5) PEP-646 可変長ジェネリックス(その6) PEP-673 Self型(その7) PEP-681 データクラス変換(その8) PEP-655 TypedDictの要素ごとに省略可・不可を指定する(その9) その他の型ヒント関連機能(その10) 正規表現 - アトミックグループとPossessive指定子(その11) 標準ライブラリ(その12) Python本体の機能追加

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 と同じような型チェックをサードパーティのクラスでも行えるようになり、将来的にはより多くのライブラリが、もっと簡単に型アノテーションに対応できるようになることが期待できます。

Copyright © 2001-2023 python.jp Privacy Policy python_japan
Amazon.co.jpアソシエイト
Amazonで他のPython書籍を検索