Pydanticは、Pythonでデータの検証(バリデーション)を実装するためのライブラリです。
基本的な入力型の検証はTypingを記述するだけで実装できるということで、最近の型ヒントを記述するPythonコードと組み合わせて使うことを想定しています。
docs.pydantic.dev
一方、Pythonには標準モジュールで、 dataclasses というのがあります。
docs.python.org
dataclassesモジュールに含まれるdataclassデコレータを使うと、型ヒントを使って簡単にデータ型を記述できます。
Pydanticはこのdataclassと互換性のある機能を提供しているので、これを試してみます。
dataclassesでの記述
main.py:
from dataclasses import dataclass @dataclass class User: id: int name: str user1 = User(id=123, name="foo") print(user1) user2 = User(id="abc", name="bar") print(user2)
意図的に user2.id はint型ではない文字列を指定しています。実行結果はこうなります。
$ python main.py User(id=123, name='foo') User(id='abc', name='bar')
標準モジュールのdataclassで作成したクラスでは、特にバリデーションの処理はないので、Pythonのコードとして実行可能であればエラーは発生しません。
ただし、mypyで型チェックをしてみると、型の不正を検出できます。
$ mypy main.py main.py:10: error: Argument "id" to "User" has incompatible type "str"; expected "int" [arg-type] Found 1 error in 1 file (checked 1 source file)
pydantic.dataclassesでの記述
dataclassをPydanticのものに切り替えてみます。 importの1行だけ変更しました。
main.py:
from pydantic.dataclasses import dataclass # ここだけ変更 @dataclass class User: id: int name: str user1 = User(id=123, name="foo") print(user1) user2 = User(id="abc", name="bar") print(user2)
実行結果はこうなります。
$ python main.py
User(id=123, name='foo')
Traceback (most recent call last):
File "/home/vagrant/tmp/pydantic/main.py", line 10, in <module>
user2 = User(id="abc", name="bar")
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/tmp/pydantic/venv/lib/python3.12/site-packages/pydantic/_internal/_dataclasses.py", line 121, in __init__
s.__pydantic_validator__.validate_python(ArgsKwargs(args, kwargs), self_instance=s)
pydantic_core._pydantic_core.ValidationError: 1 validation error for User
id
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='abc', input_type=str]
For further information visit https://errors.pydantic.dev/2.10/v/int_parsing
pydanticのValidationErrorが発生しました。
標準モジュールのdataclassesと同様の書き方で、pydanticをすぐに導入できるのは興味深いです。
pydanticのドキュメントには、BaseModelを継承するのとdataclassを使うのでは、機能的な差があるとも書かれているので、利用する際には気を付けておいたほうが良さそうです。