プログラミング
記事内に商品プロモーションを含む場合があります

Python|Pydanticで型安全なデータクラスを作ろう!

Aru

Pythonの型ヒントは、実行時の型チェックを行なってくれません。Pythonでアプリケーション開発を行う場合、データの型や形式が期待通りであることを保証したい場合があります。これを簡単に行うためのライブラリがPydanticです。この記事では、Pydanticの使い方について、具体的なサンプルコードを交えて解説します。

最近、チャットの話題に出て、興味があって調べたのでブログ記事にまとめました

Pydanticとは

Pydanticは、Pythonの型ヒント(type hints)を活用してデータの検証(validation)と設定の管理を行うためのライブラリです。Pydanticを使用すると、少ないコード量でデータスキーマ定義と、検証を実装することができます。

Pydanticを利用しない場合の例

まずは、Pydanticを使用しないシンプルなデータクラスの例です。

クラス定義と利用例

従来のPythonでは、以下のようにクラスを定義します。

class User :
    name : str
    age : int
    def __init__(self, name, age) :
        self.name = name
        self.age = age
    def __repr__ (self) :
        return f"User(name={self.name}, age={self.age})"

__init__は初期化(コンストラクタ)、__repr__はクラスを文字列表現するための特殊メソッドの定義です。

以下のコードでクラスを使ってインスタンスを作成することができます。

# 正しい型のインスタンス
user01 = User(name="hoge", age=10)

# ageに文字列を渡したインスタンス
user02 = User(name="fuga", age="xxxx")

user02ageは文字列ですが、このコードを実行しても、エラーは発生しません。

実行結果
User(name=hoge, age=10)
User(name=fuga, age=xxxx)

ご覧のように、user02ageには、期待する整数ではなく文字列がそのまま格納されてしまいます。

型ヒントで指定の問題点

Pythonの型ヒントは、コードの可読性を高め、開発をサポートするためのものです。しかし、実行時の型チェックは行われません。そのため、上の例のように誤った型のデータが渡されても、プログラムはそのまま実行され、後続の処理で予期せぬエラーを引き起こす可能性があります。

Pydanticでは、これをチェックする機能を提供します。

Pydanticを利用した記述

インストール

Pydanticを使用するにはインストールする必要があります。以下のコードをコマンドラインで実行してライブラリをインストールします。

pip install pydantic

クラス定義

次に、Pydanticを使って同じデータクラスを定義してみます。Pydanticを使用するには、BaseModelを継承するだけです。

from pydantic import BaseModel

class UserPydantic(BaseModel) :
    name : str
    age : int

先ほどの例にあった__init__などは記述する必要はありません。たった2行で定義が完成です。

では、UserPydanticクラスを使ってインスタンスを作成します。

try :
    # 正しい型のインスタンス
    user11 = UserPydantic(name="hoge", age=10)
    # ageに文字列を渡したインスタンス
    user12 = UserPydantic(name="fuga", age="xxxx")
except Exception as e :
    print("-" * 80)
    print(e)
    print("-" * 80)
    user12 = None

このコードを実行すると、user12を作成しようとした部分でValidationErrorが発生します。

エラーが発生するのがわかっているのでtry~exceptで捕獲しています

実行結果
--------------------------------------------------------------------------------
1 validation error for UserPydantic
age
  Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='xxxx', input_type=str]
    For further information visit https://errors.pydantic.dev/2.10/v/int_parsing
--------------------------------------------------------------------------------

このように、Pydanticは実行時にデータの検証を行い、期待した型でない場合はエラーを返してくれます。これにより、不適切なデータが後続の処理に進むのを防ぐことができます。

PydanticがValidationErrorを発生させるということは、通常のPythonの例外と同様にtry...exceptブロックでエラーを捕捉できることを意味します。これにより、プログラムの実行を中断させることなく、適切にエラー処理することができます。

例えば、Webアプリケーションでユーザーからの入力を受け取る際に、バリデーションエラーが発生した場合、単にプログラムを終了させるのではなく、ユーザーに「入力データが正しくありません」といったメッセージを返すことができます。

シリアライズ

Pydanticモデルは、データの検証だけでなく、PythonオブジェクトをJSONや辞書形式に簡単に変換する機能も提供します。

from pydantic import BaseModel

class UserPydantic(BaseModel) :
    name : str
    age : int

user11 = UserPydantic(name="hoge", age=10)
json_string = user11.model_dump_json()

print(json_string)
# 出力: {"name":"hoge","age":10}

model_dump_json()メソッドを呼び出すだけで、オブジェクトがJSON文字列に変換されます。この機能は、APIからレスポンスを返す際に非常に便利です。

デシリアライズ

デシリアライズは、シリアライズの逆のプロセスです。文字列などの形式からPydanticモデルのインスタンスを生成することを指します。これは、外部からJSON形式のデータを受け取った際に、Pythonオブジェクトに変換し、同時にそのデータの検証を行う場合に非常に役立ちます。

UserPydantic.model_validate_json()メソッドを使用すると、JSON文字列から直接モデルのインスタンスを生成できます。この際、内部で自動的にデータ検証も行われます。

from pydantic import BaseModel

class UserPydantic(BaseModel):
    name: str
    age: int

# シリアライズされたJSON文字列
json_string = '{"name":"hoge","age":10}'

# JSON文字列からPydanticモデルのインスタンスを生成(デシリアライズ)
user = UserPydantic.model_validate_json(json_string)
print(user)
# 出力: name='hoge' age=10

このように、model_validate_json()を使用することで、データの変換と検証を同時に安全に行うことができます。

try~exceptを使えば、エラー発生時の処理にも対応できます

まとめ

Pydanticを利用することで、以下のようなメリットが得られます。

  • 型安全:
    実行時に型チェックが行われ、不適切なデータを排除
  • コードの簡潔さ:
    ボイラープレートコードが減り、クラス定義が非常にシンプル化

Pydanticを使ってコードをシンプルにすることで、開発者はより重要なロジックの記述に集中できます。

便利そうですが、最近はToyプログラム的なものしか作らないので、あまり使う機会はなさそうです。

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
ある/Aru
ある/Aru
IT&機械学習エンジニア/ファイナンシャルプランナー(CFP®)
専門分野は並列処理・画像処理・機械学習・ディープラーニング。プログラミング言語はC, C++, Go, Pythonを中心として色々利用。現在は、Kaggle, 競プロなどをしながら悠々自適に活動中
記事URLをコピーしました