はじめに
Pythonでデータ構造を定義する際によく使われるdataclassとpydantic。
この記事では、それぞれの特徴や使い分けポイントを、サンプルコードで示す。
dataclassとは
Python 3.7から標準搭載されたデータ構造用のデコレータ。
クラス定義を簡潔にし、__init__や__repr__などのメソッドを自動生成。
example.py
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
in_stock: bool
product = Product("Coffee", 2.99, True)
print(product)
# 出力例: Product(name='Coffee', price=2.99, in_stock=True)
pydanticとは?
型ヒントに基づいたバリデーションやシリアライズを自動で行うライブラリ。
APIや外部データの受け取り時に特に有用
example.py
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
in_stock: bool
product = Product(name="Coffee", price=2.99, in_stock=True)
print(product)
# 出力例: name='Coffee' price=2.99 in_stock=True
dataclassとpydanticの比較
項目 | dataclass | pydantic |
---|---|---|
バリデーション | 手動で実装が必要 | 型に基づき自動で実施 |
初期化 | 型ヒントはヒントのみ | 型変換・バリデーションを自動実施 |
パフォーマンス | 軽量 | やや重い(バリデーション分) |
利用シーン | シンプルなデータ構造 | 外部データAPI / 設定ファイル等 |
シリアライズ | 標準機能なし | JSON等への変換が容易 |
dataclassでバリデーションを行うには?
__post_init__メソッドを使って手動でバリデーション
example.py
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
def __post_init__(self):
if self.age < 0:
raise ValueError("age must be non-negative")
user = User(name="Alice", age=20) # OK
user = User(name="Bob", age=-5) # ValueError
pydanticのバリデーション例
型変換やバリデーションが自動で行われる
example.py
from pydantic import BaseModel, PositiveInt
class User(BaseModel):
name: str
age: PositiveInt
user = User(name="Alice", age="20") # 自動でint変換しバリデーション
user = User(name="Bob", age=-5) # ValidationError
pydantic.dataclassesによるハイブリッド
@pydantic.dataclasses.dataclassでdataclassの書き心地+pydanticのバリデーション
example.py
from pydantic.dataclasses import dataclass
from pydantic import PositiveInt
@dataclass
class User:
name: str
age: PositiveInt
user = User(name="Alice", age="30") # 自動でint変換しバリデーション
user = User(name="Bob", age=-1) # ValidationError
使い分けの指針
dataclass
内部的なデータ構造や単純な値オブジェクトに最適。
バリデーションや型変換が不要な場合。
pydantic
外部入力やAPIレスポンスなど、信頼できないデータの取り扱い。
バリデーション・型変換・シリアライズが必要な場合
まとめ
dataclassはシンプル・軽量な用途に、pydanticは堅牢なバリデーションや外部データ処理に強み。
pydantic.dataclassesで両者の良いとこ取りも可能。