You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Pydantic将映射的键值分别解析为模型属性?

用Pydantic解析键为属性名、值为属性值的映射数据

针对这种单键值对格式的嵌套数据,有三种高效的模型修改方案,直接适配原始数据结构完成解析:

方法一:给Household模型添加前置字段验证器

在Household的pets字段上添加前置验证逻辑,批量将原始单键值对转换为Pet模型可识别的格式:

from typing import Literal, List
from pydantic import BaseModel, field_validator

class Pet(BaseModel):
    name: str
    species: Literal["dog", "cat"]

class Household(BaseModel):
    pets: List[Pet]

    @field_validator("pets", mode="before")
    def transform_pet_format(cls, raw_pets):
        # 遍历每个宠物字典,提取键作为name、值作为species
        return [
            {"name": list(pet.keys())[0], "species": list(pet.values())[0]}
            for pet in raw_pets
        ]

使用示例:

data = {
    "pets": [
        {"felix": "cat"},
        {"rover": "dog"},
        {"snuffles": "dog"},
    ]
}

household = Household(**data)
print(household.pets)
# 输出:[Pet(name='felix', species='cat'), Pet(name='rover', species='dog'), Pet(name='snuffles', species='dog')]

方法二:让Pet模型直接兼容单键值对输入

通过model_validator让Pet模型本身支持解析单键值对,无需修改Household模型:

from typing import Literal, Any, Dict
from pydantic import BaseModel, model_validator

class Pet(BaseModel):
    name: str
    species: Literal["dog", "cat"]

    @model_validator(mode="before")
    def parse_single_key_input(cls, values: Any) -> Dict[str, Any]:
        # 若输入是单键值对字典,自动转换为标准字段结构
        if isinstance(values, dict) and len(values) == 1:
            name, species = next(iter(values.items()))
            return {"name": name, "species": species}
        return values

class Household(BaseModel):
    pets: list[Pet]

这种方式下,直接用Household(**data)即可完成解析,Pet模型会自动处理格式转换。

方法三:用RootModel封装原始宠物结构

借助Pydantic的RootModel定义原始单键值对的结构,再转换为Pet模型,适合需要明确区分原始输入和最终模型的场景:

from typing import Literal, Dict
from pydantic import BaseModel, RootModel

class PetRaw(RootModel[Dict[str, Literal["dog", "cat"]]]):
    def to_pet(self) -> "Pet":
        name, species = next(iter(self.root.items()))
        return Pet(name=name, species=species)

class Pet(BaseModel):
    name: str
    species: Literal["dog", "cat"]

class Household(BaseModel):
    pets: list[PetRaw]

    @field_validator("pets", mode="after")
    def convert_to_pet_model(cls, raw_pets):
        return [raw_pet.to_pet() for raw_pet in raw_pets]

内容的提问来源于stack exchange,提问作者SlyFox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:35:30