Pydantic如何用parse_obj解析含异构元组字段的嵌套模型
Pydantic 混合格式输入解析方案
针对嵌套模型同时存在标准字典格式、位置元组格式的解析需求,直接用Pydantic自带的字段前置校验器即可实现,不需要手写全量遍历转换逻辑。
实现步骤
- 先修正原模型定义的笔误:Pydantic中布尔类型为内置
bool,不存在Boolean类型。 - 给外层
Qux模型的field3字段加前置校验器:在Pydantic默认类型解析前,把列表内的位置元组格式元素,按Bar模型的字段声明顺序转换为字典,再交给默认解析逻辑生成Bar实例即可,同时天然兼容标准字典格式的输入。
完整可运行代码
from pydantic import BaseModel, validator from typing import List class Bar(BaseModel): f1: str f2: float f3: bool class Qux(BaseModel): field1: str field2: float field3: List[Bar] @validator("field3", pre=True) def parse_tuple_format_bar(cls, value): # 取Bar模型的字段声明顺序,无需硬编码 bar_fields = list(Bar.__fields__.keys()) parsed_list = [] for item in value: # 如果是位置元组/列表格式,转成字段映射字典 if isinstance(item, (list, tuple)): item = {field: item[idx] for idx, field in enumerate(bar_fields)} parsed_list.append(item) return parsed_list # 测试输入数据 input_data = { "field1": "bar", "field2": 3.14, "field3": [ ["aaa", 2.71, True], ["bbb", -1, False] ] } # 直接调用parse_obj即可正常解析 qux_instance = Qux.parse_obj(input_data) print(qux_instance) # 输出:field1='bar' field2=3.14 field3=[Bar(f1='aaa', f2=2.71, f3=True), Bar(f1='bbb', f2=-1.0, f3=False)]
关键说明
pre=True参数是核心:标记该校验逻辑在Pydantic默认类型转换之前执行,此时拿到的是原始输入数据,不会提前触发类型不匹配的报错。- 自动适配字段顺序:通过
Bar.__fields__.keys()取模型声明的字段顺序,后续修改Bar的字段定义、增减字段时,不需要同步修改校验逻辑。 - 兼容双格式:如果
field3列表里同时存在位置元组和标准字典格式的Bar数据,这段逻辑也能正常解析,不需要额外分支处理。 - 如果你用的是Pydantic V2版本,只需要把
@validator替换为@field_validator,同时指定参数mode="before"即可,核心转换逻辑完全不变。
内容的提问来源于stack exchange,提问作者poolfroof
相关产品推荐
相关产品推荐

