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

如何区分字段完全相同的Pydantic模型,解决序列化后类型识别错误问题

问题核心原因

Pydantic 1.x 对 Union 类型默认采用左匹配规则:反序列化时会返回第一个符合字段结构的模型。你的 DataA 和 DataB 结构完全一致,因此反序列化时永远返回排在 Union 定义第一位的 DataA。

官方推荐解决方案:使用鉴别器(discriminator)字段

这是 Pydantic 专门为同构多子类场景设计的标准方案,不属于 hack 实现,只需要给基类增加一个类型标识字段,配合 Union 的鉴别器参数即可实现精准匹配:

from abc import ABC
from pydantic import BaseModel, Field
from typing import Union, Literal

class Data(BaseModel, ABC):
    """ base class for a Member """
    # 新增鉴别器字段,枚举所有子类的类型标识
    type: Literal["data_a", "data_b"]
    number: float

class DataA(Data):
    """ A type of Data"""
    # 子类指定固定的类型标识默认值,不需要手动赋值
    type: Literal["data_a"] = "data_a"
    pass

class DataB(Data):
    """ Another type of Data """
    type: Literal["data_b"] = "data_b"
    pass

class Container(BaseModel):
    """ container holds a subclass of Data """
    # 指定用type字段作为鉴别器匹配对应子类
    data: Union[DataA, DataB] = Field(..., discriminator="type")

# 初始化和之前完全一致,不需要手动给type赋值
data = DataB(number=1.0)
container = Container(data=data)

string = container.json()
new_container = Container.parse_raw(string)

print(type(new_container.data).__name__)
# >>> DataB

该方案不需要额外自定义校验逻辑,序列化时会自动带上类型标识字段,反序列化时会根据标识直接匹配对应子类,性能和可维护性都远优于自定义 hack 方案。如果不想对外暴露这个标识字段,也可以配合 Field(..., exclude=True) 在序列化时隐藏,反序列化时单独传入类型信息即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:09:01