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

Pydantic中List[Union[TypeA, TypeB]]仅识别首个类型问题求助

问题原因

在Pydantic 1.x版本中,处理List[Union[TypeA, TypeB]]这类类型时,会按Union中类型的顺序依次尝试匹配。如果TypeB的字段完全包含在TypeA的字段中(或TypeB的字段可被TypeA模型解析),Pydantic会优先将对象解析为Union列表里的第一个匹配类型(即TypeA),最终导致TypeB实例被意外转成TypeA。

典型复现代码:

from pydantic import BaseModel
from typing import List, Union

class TypeA(BaseModel):
    name: str

class TypeB(BaseModel):
    name: str
    value: int

class ReturnObject(BaseModel):
    parameters: List[Union[TypeA, TypeB]]

# 实例化后出现类型转换问题
obj = ReturnObject(parameters=[TypeA(name="a"), TypeB(name="b", value=10)])
print(obj.parameters)
# 输出: [TypeA(name='a'), TypeA(name='b')] —— TypeB被强制转为TypeA
解决办法

1. 使用鉴别器(Discriminator)

给两个模型添加共同的标识字段,让Pydantic能明确区分不同类型,这是最可靠的方案:

from pydantic import BaseModel, Field
from typing import List, Union

class TypeA(BaseModel):
    type: str = Field("type_a", const=True)
    name: str

class TypeB(BaseModel):
    type: str = Field("type_b", const=True)
    name: str
    value: int

class ReturnObject(BaseModel):
    parameters: List[Union[TypeA, TypeB]] = Field(discriminator="type")

obj = ReturnObject(parameters=[TypeA(name="a"), TypeB(name="b", value=10)])
print(obj.parameters)
# 输出: [TypeA(type='type_a', name='a'), TypeB(type='type_b', name='b', value=10)]

2. 调整Union中类型的顺序

如果TypeA的字段不是TypeB的子集,可把字段更具体的TypeB放在Union前面,让Pydantic优先匹配更复杂的类型。但该方案仅适用于类型字段有明确包含关系的场景:

class ReturnObject(BaseModel):
    parameters: List[Union[TypeB, TypeA]]  # 将TypeB放在Union的第一位

obj = ReturnObject(parameters=[TypeA(name="a"), TypeB(name="b", value=10)])
print(obj.parameters)
# 输出: [TypeA(name='a'), TypeB(name='b', value=10)]

3. 显式使用parse_obj_as强制指定类型

在构造列表时,用parse_obj_as明确告知Pydantic要解析的目标类型,避免自动匹配:

from pydantic import parse_obj_as

data = [
    parse_obj_as(TypeA, {"name": "a"}),
    parse_obj_as(TypeB, {"name": "b", "value": 10})
]
obj = ReturnObject(parameters=data)
print(obj.parameters)
# 输出: [TypeA(name='a'), TypeB(name='b', value=10)]

4. 升级到Pydantic 2.x

Pydantic 2.x对Union类型的匹配逻辑做了优化,会优先选择最匹配的类型而非按顺序匹配,多数场景下无需额外处理就能正确识别TypeA和TypeB。

内容的提问来源于stack exchange,提问作者Mr. Developerdude

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:52:34