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

如何将ClassVar Literal用作Pydantic字段的鉴别器?

在Pydantic 2中使用类属性作为鉴别器

问题核心在于:ClassVar类型的字段会被Pydantic排除在模型的Schema之外,而鉴别器要求目标字段必须是模型Schema的一部分,因此直接用ClassVar会触发报错。

下面提供两种可行的解决方法:


方法一:使用不可变实例字段模拟类属性

将animal_type定义为实例字段,但通过frozen=True配置使其不可修改,同时固定字面量值。这样既满足鉴别器对Schema字段的要求,又能保证该字段的值不会被实例篡改,效果近似类属性。

from pydantic import BaseModel, Field, ConfigDict
from typing import Literal

class Cat(BaseModel):
    model_config = ConfigDict(frozen=True)
    animal_type: Literal['cat'] = 'cat'

class Dog(BaseModel):
    model_config = ConfigDict(frozen=True)
    animal_type: Literal['dog'] = 'dog'

class PetCarrier(BaseModel):
    contains: Cat | Dog = Field(discriminator='animal_type')

方法二:通过计算字段暴露ClassVar

使用@computed_field装饰器,将ClassVar的值映射为一个Schema可见的字段,这样既保留ClassVar作为类属性的便捷性,又能让Pydantic识别该字段作为鉴别器。

from pydantic import BaseModel, Field, computed_field
from typing import Literal, ClassVar

class Cat(BaseModel):
    animal_type: ClassVar[Literal['cat']] = 'cat'

    @computed_field(return_type=Literal['cat'])
    def animal_type(self) -> Literal['cat']:
        return self.__class__.animal_type

class Dog(BaseModel):
    animal_type: ClassVar[Literal['dog']] = 'dog'

    @computed_field(return_type=Literal['dog'])
    def animal_type(self) -> Literal['dog']:
        return self.__class__.animal_type

class PetCarrier(BaseModel):
    contains: Cat | Dog = Field(discriminator='animal_type')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:07:17