Pydantic で Generic を扱う
Pydantic 1 系のGenericModelを使うと、型を指定しながら柔軟にモデルを定義できる。共通の構造を持つモデルを、内部のデータ型だけ差し替えて再利用したい場合に役立つ。コード例は Python 3.12.3、Pydantic 1.10.24 で動作を確認した。
| from typing import Generic, TypeVar
from pydantic import BaseModel
from pydantic.generics import GenericModel
InnerT = TypeVar('InnerT')
class Outer(GenericModel, Generic[InnerT]):
data: InnerT | None
class InnerX(BaseModel):
x: int = 1
class InnerY(BaseModel):
y: str = "foo"
class InnerZ(BaseModel):
z: bool = True
ModelX = Outer[InnerX]
ModelY = Outer[InnerY]
ModelZ = Outer[InnerZ]
print(ModelX(data=InnerX()).dict())
# {'data': {'x': 1}}
print(ModelY(data=InnerY()).dict())
# {'data': {'y': 'foo'}}
print(ModelZ(data=InnerZ()).dict())
# {'data': {'z': True}}
|
モデルの動的生成
型のパラメータを切り替える Generic に対して、フィールドの構成自体を実行時に決めたい場合はcreate_modelでモデルを生成できる。
| from pydantic import BaseModel, create_model
class FooModel(BaseModel):
foo: str
bar: int = 123
BarModel = create_model(
'BarModel',
apple='russet',
banana='yellow',
__base__=FooModel,
)
print(BarModel)
#> <class 'pydantic.main.BarModel'>
print(BarModel.__fields__.keys())
#> dict_keys(['foo', 'bar', 'apple', 'banana'])
|
参考