nestしてくとこんがらがるのでmemo
pydantic の 基礎から行きます
BaseModel
これでモデルを作れる。dictを入れて使うときは **
をつけて keyword arguments に展開させる。
keyword arguments とは
よくわかってないけど多分こんな感じ。 コロン式がイコール式になる
# dictの場合
{ "a": 1 }
# keyword argumentsの場合
(a=1)
1. BaseModel
from pydantic import BaseModel
# 作りたいもの、goal
{
'name': 'a'
}
# model
class A(BaseModel):
name: str
## モデルへの値の入れ方
# 1. object方式
obj = A(name="a")
# 2. dict方式
obj = A(**{"name": "a"})
# 3. dictのままいれるとエラー TypeError: __init__() takes exactly ....
>>> A({"name": "a"})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pydantic/main.py", line 397, in pydantic.main.BaseModel.__init__
TypeError: __init__() takes exactly 1 positional argument (2 given)
# 使い方
obj.dict() # {'name': 'a'} <--- type=dict
obj.json() # '{"name": "a"}' <--- type=str
TypeError: __init__() takes exactly N positional argument(N given)
これは dict だめだぞ! あるある。
2. Nested Model
nestするときは複数classにする
# 作りたいもの
{
'a': {
'root': 1
}
}
# model
class A(BaseModel):
root: int
class B(BaseModel):
a: A
# 1. 子供のmodel使う方式
obj = B(a=A(root=1))
# 2. 子供はdict方式
obj = B(a=A(**{"root": 1}))
# 3. 全部dict方式
obj = B(**{'a': {'root': 1}})
# 使い方
obj.dict() # {'a': {'root': 1}} <--- type=dict
obj.json() # '{"a": {"root": 1}}' <--- type=str
3. Deeper nested model
さらにnestさせると、dictとか こんがり始めます
# 作りたいもの
{
'c': {
'b': {
'a': 1
}
}
}
# model
class A(BaseModel):
a: int
class B(BaseModel):
b: A
class C(BaseModel):
c: B
# 1. 子供のmodel使う方式
obj = C(c=B(b=A(a=1)))
# 2. 全部dict方式
obj = C(**{"c": {"b": {"a": 1}}})
# 3. 子供はmodelだけどdictで入れたい時
objA = A(a=1) # {'a': 1}
obj = C(**{"c": {"b": objA.dict()}}) # <----- modelはdictにしながら代入
# 4. 実は dict にしなくても動く
obj = C(**{"c": {"b": objA}})
# 使い方
obj.dict() # {'c': {'b': {'a': 1}}}
obj.json() # '{"c": {"b": {"a": 1}}}'
まとめ
- nestされたmodelを使うときは、値を入れるときに object / dict を統一するように気をつける。
-
TypeError: __init__() takes exactly ....
はとにかく いれる値が間違ってるってこと