4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[pydantic の基礎] よくあるエラーと nested model を一発でインスタンスにするコツ

Posted at

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}}}'

まとめ

  1. nestされたmodelを使うときは、値を入れるときに object / dict を統一するように気をつける。
  2. TypeError: __init__() takes exactly .... はとにかく いれる値が間違ってるってこと
4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?