如何将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
相关产品推荐
相关产品推荐

