1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pydanticについて

1
Posted at

概要

pythonの型ヒントを強化するパッケージ。
beartypeがバリデーションだけだったのに対して、こちらは変換なども行うことができる。
v1とv2があるらしいが、基本的にv2ベースでまとめていく。

インストール

組み込みパッケージではないので、別途インストールする必要あり。

pip install pydantic

簡単な利用例

BaseModel

クラス定義時にBaseModelを継承すると、pydanticの各種バリデートの仕組みを利用できるようになる。

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

以下のように呼び出せる。

# 各フィールドを指定して呼び出す
SimpleUser(name="John", age=30)
# jsonオブジェクトで値を渡す
SimpleUser.model_validate({"name": "John", "age": 30})
# json文字列で値を渡す
SimpleUser.model_validate(json.dumps({"name": "John", "age": 30}))

intの値を文字列で渡した場合、自動でintに変換してくれる。
ただし、自動で変換できないような文字列の場合はエラーになる。

print(SimpleUser(name="John", age='30')) # name='John' age=30
print(SimpleUser(name="John", age='Invalid')) # エラー

なお、通常のフィールドを指定して初期化の場合は、IDE上でワーニングを表示してくれるが、jsonオブジェクトやjson文字列による初期化の場合は、わーニングが表示されない。

SimpleUser(name="John", age='30') # IDE上でワーニングあり
SimpleUser.model_validate({"name": "John", "age": "30"}) # ワーニングなし

RootModel

BaseModelの特殊ケース。
実体としてはBaseModelを継承して定義されている。
利用方法としては、BaseModelとほぼ同じであるが、RootModelはフィールド定義ができない。
クラスの初期化時に渡されるオブジェクトを格納するフィールドのみ持つクラスとなる。

class CustomConfig(RootModel[dict[str, Any]]):
    def get_version(self) -> Optional[str]:
        return self.root.get("version")

config = CustomConfig({"flag": True, "version": "1.0"})
print(config.get_version()) # "1.0"
print(config.root) # 入力したオブジェクトが表示される

field_validator

フィールドに対してバリデーションを付与できる。
以下はnameにバリデーションを付与した例。

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

    # modeにはbefore, afterがある
    # before : 変換前に呼ばれる
    # after : 変換後に呼ばれる (str -> int など)
    # wrap : (cls, v, info)の3つの引数を受け取る。infoで検証関数の情報を取得できる
    @field_validator('name', mode='before')
    def name_validator(cls, v):
        if len(v) < 1 or len(v) > 4:
            raise ValueError('must be between 1 and 4 characters')
        return v

以下のように実行時にエラーになる。
なお、IDE上のワーニングなどは表示されない。

User(name="John", age=30) # OK
User(name="John2nd", age=30) # エラー

dataclass

pythonの組み込みAPIにdataclassデコレータが存在するが、pydanticにも同名のデコレータが存在する。
機能的にはほぼ同一であるが、標準のdataclassの機能に加えて、バリデーション機能が追加されている。

from pydantic.dataclasses import dataclass
@dataclass
class SimpleUser:
    name: str
    age: int

# BaseModelの場合と同様に、"30"が30として自動で変換される
print(SimpleUser(name="John", age="30")) # name='John' age=30

なお、標準のdataclassの場合は、型が間違っていてもそのままインスタンスが作成される。

from dataclasses import dataclass
@dataclass
class PythonUser:
    name: str
    age: int

# ageは文字列から変換されずそのまま入る
print(PythonUser(name="John", age="30")) # name='John' name='30'

TypeAdapter

任意の型に対する検証、正規化などの機能を提供する。

以下の例では、元データの一部に文字列となっている箇所があるが、TypeAdapterを通してintに正規化されている。

ty = TypeAdapter(list[int])
print(ty.validate_python(['1', 2, '3'])) # [1, 2, 3]

その他

その他のAPIについては、ドキュメントを参照。

終わりに

pydanticについて調査したので簡単にまとめました。
beartypeと同様に、pythonの通常の型ヒントで十分なケースがほとんどだと思うので、導入する際には、pydanticで何を実現したいのか明確にしておく必要があるかと思います。
また、データの訂正機能がある点を考慮すると、データクレンジングをプログラム側で行うケースなどでは有用なのではないかと思いました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?