如何根据已解析字典中的值更改 pydantic 解析的类型?
How can I change the type pydantic parses according to a value in the parsed dictionary?
我希望 pydantic 根据输入值选择用于解析输入的模型。这可能吗?
MVCE
我有一个看起来很像这个的 pydantic 模型:
from typing import List, Literal
from pydantic import BaseModel
class Animal(BaseModel):
name: str
type: Literal["mamal", "bird"]
class Bird(Animal):
max_eggs: int
class Mamal(Animal):
max_offspring: int
class Config(BaseModel):
animals: List[Animal]
cfg = Config.parse_obj(
{
"animals": [
{"name": "eagle", "type": "bird", "max_eggs": 3},
{"name": "Human", "type": "mamal", "max_offspring": 3},
]
}
)
print(cfg.json(indent=4))
给予
{
"animals": [
{
"name": "eagle",
"type": "bird"
<-- missing max_offspring, as "Animal" was used instead of Bird
},
{
"name": "Human",
"type": "mamal"
<-- missing max_offspring, as "Animal" was used instead of Mamal
}
]
}
我知道我可以在 Animal
中设置 Config.extra="allow"
,但这不是我想要的。我希望 pydantic 看到带有 'type': 'mamal'
的字典应该使用 Mamal
模型来解析。
这可能吗?
您可以为每个子 class 添加具体的文字来区分它们,并将它们按 Union
从更具体到更不具体的顺序排列。像这样:
class Animal(BaseModel):
name: str
type: str
class Bird(Animal):
type: Literal["bird"]
max_eggs: int
class Mamal(Animal):
type: Literal["mamal"]
max_offspring: int
class Config(BaseModel):
animals: List[Union[Bird, Mamal, Animal]] # From more specific to less
我希望 pydantic 根据输入值选择用于解析输入的模型。这可能吗?
MVCE
我有一个看起来很像这个的 pydantic 模型:
from typing import List, Literal
from pydantic import BaseModel
class Animal(BaseModel):
name: str
type: Literal["mamal", "bird"]
class Bird(Animal):
max_eggs: int
class Mamal(Animal):
max_offspring: int
class Config(BaseModel):
animals: List[Animal]
cfg = Config.parse_obj(
{
"animals": [
{"name": "eagle", "type": "bird", "max_eggs": 3},
{"name": "Human", "type": "mamal", "max_offspring": 3},
]
}
)
print(cfg.json(indent=4))
给予
{
"animals": [
{
"name": "eagle",
"type": "bird"
<-- missing max_offspring, as "Animal" was used instead of Bird
},
{
"name": "Human",
"type": "mamal"
<-- missing max_offspring, as "Animal" was used instead of Mamal
}
]
}
我知道我可以在 Animal
中设置 Config.extra="allow"
,但这不是我想要的。我希望 pydantic 看到带有 'type': 'mamal'
的字典应该使用 Mamal
模型来解析。
这可能吗?
您可以为每个子 class 添加具体的文字来区分它们,并将它们按 Union
从更具体到更不具体的顺序排列。像这样:
class Animal(BaseModel):
name: str
type: str
class Bird(Animal):
type: Literal["bird"]
max_eggs: int
class Mamal(Animal):
type: Literal["mamal"]
max_offspring: int
class Config(BaseModel):
animals: List[Union[Bird, Mamal, Animal]] # From more specific to less