🤗
ネストされたdictやjsonからdataclassを作成したいならpydanticが便利
ネストされたdictやjsonからdataclassを作成するのは面倒くさい
ネストされたdictやjsonからdataclassを作成するのは面倒くさいです.
例えば以下のようなdictがあったとします.
data = {
"name": "hoge",
"age": 20,
"address": {
"country": "Japan",
"city": "Tokyo",
"street": "hoge street",
},
}
このdictから以下のようなdataclassを作成したいとします.
from dataclasses import dataclass
@dataclass
class Address:
country: str
city: str
street: str
@dataclass
class Person:
name: str
age: int
address: Address
このような時,例えば辞書を展開してdataclassを作成しようとすると以下のようになります.
person = Person(**data)
print(person)
# Person(name='hoge', age=20, address={'country': 'Japan', 'city': 'Tokyo', 'street': 'hoge street'})
見ての通り,Addressも展開してデータクラスにしてほしいのに,dictのままになってしまいます.これをどうにかしようとすると,メソッドを書いたり色々しないといけなく,面倒です.
このような時,pydanticを使うと便利です.
pydanticを使う
pydanticを使うときは,dataclassesの代わりにpydanticのdataclassを使います.
from pydantic.dataclasses import dataclass
# 以下は先程と同じ
これで先ほどのコードを実行すると,以下のようになります.
person = Person(**data)
print(person)
# Person(name='hoge', age=20, address=Address(country='Japan', city='Tokyo', street='hoge street'))
しっかりAddressもdataclassになっています.
その他
TypeAdapter
pydantic v2から追加されたTypeAdapterを使うと,dictやjsonからdataclassを作成する際に,そのまま引数として渡せます.
詳しくはココを参照
from pydantic import TypeAdapter
datas: list[Person] = ...
json: str = ...
# persons = [Person(**data) for data in datas]の代わりに
persons = TypeAdapter(list[Person]).dump_python(datas) # dictの場合
persons = TypeAdapter(list[Person]).dump_json(json) # jsonの場合
BaseModelとdataclass
pydanticにはBaseModelというクラスがあり,dataclassとよく似ていますが,違いもあるようですので,以下の記事を参照して使い分けるのが良いと思います.
参考になるサイト
個人的にはBaseModelじゃないとないメソッドがあったりするので,BaseModelを使っています.
Discussion