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

如何在Pydantic中不使用嵌套模型实现鉴别联合?

解决方案:直接使用带鉴别器的联合类型调用model_validate

在Pydantic v2.7中,不需要嵌套模型或RootModel,直接对标记了鉴别器的Annotated[Union[...]]类型调用model_validate,就能得到对应子类的实例,实现和普通BaseModel一致的属性访问体验。

代码实现

from typing import Literal, Union, Annotated
from pydantic import BaseModel, Field, model_validate

class Cat(BaseModel):
    pet_type: Literal["cat"]
    meows: int

class Dog(BaseModel):
    pet_type: Literal["dog"]
    barks: float

class Lizard(BaseModel):
    pet_type: Literal["reptile", "lizard"]
    scales: bool

Animal = Annotated[
    Union[Cat, Dog, Lizard],
    Field(discriminator="pet_type"),
]

# 直接对Annotated联合类型执行验证
animal = model_validate({"pet_type": "cat", "meows": 3}, annotation=Animal)

# 直接访问属性,无需.root
print(animal.pet_type)  # 输出: cat
print(animal.meows)     # 输出: 3

# 验证实例类型
print(isinstance(animal, Cat))  # 输出: True

核心原理

Pydantic v2的model_validate函数支持通过annotation参数指定要验证的类型,这里传入带鉴别器的联合类型后,函数会自动根据pet_type字段匹配对应的子类,返回该子类的实例,完全保留原生BaseModel的属性访问方式。

简化调用(可选)

如果需要频繁创建实例,可以封装一个工厂函数,省去每次传递annotation的步骤:

def create_animal(data: dict) -> Animal:
    return model_validate(data, annotation=Animal)

# 使用示例
dog = create_animal({"pet_type": "dog", "barks": 2.0})
print(dog.barks)  # 输出: 2.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:57:03