VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Pydantic多态模型:用鉴别器构建类型安全的API接口

第一章:多态模型基础
1.1 多态概念解析
在电商系统中,订单可能包含多种支付方式:

PYTHON

class Payment(BaseModel):
    amount: float
    currency: str = "USD"


class CreditCardPayment(Payment):
    card_number: str
    expiry_date: str


class AlipayPayment(Payment):
    account_id: str
    auth_code: str

传统多态实现需要手动类型判断:

PYTHON

# 反模式:使用条件判断路由类型
def process_payment(data: dict):
    if "card_number" in data:
        return CreditCardPayment(**data)
    elif "account_id" in data:
        return AlipayPayment(**data)
    else:
        raise ValueError("未知支付类型")

Pydantic的鉴别器机制通过字段显式声明类型,实现自动化路由。

第二章:鉴别器核心机制
2.1 基础鉴别器定义
PYTHON

from pydantic import BaseModel, Field


class Animal(BaseModel):
    type: str = Field(..., alias="_type", discriminator="animal_type")


class Dog(Animal):
    animal_type: Literal["dog"] = "dog"
    breed: str


class Cat(Animal):
    animal_type: Literal["cat"] = "cat"
    lives_left: int


# 自动解析示例
data = {"_type": "dog", "breed": "Golden Retriever"}
animal = Animal.parse_obj(data)  # 自动实例化为Dog类型

2.2 动态解析配置
PYTHON

from pydantic import create_model

vehicle_models = {
    "car": create_model("Car", speed=(float, ...)),
    "plane": create_model("Plane", altitude=(float, ...))
}


class Vehicle(BaseModel):
    vehicle_type: str = Field(..., discriminator="vehicle_type")
    __root__: Union[tuple(vehicle_models.values())]  # 动态联合类型

第三章:嵌套多态模型
3.1 多层鉴别器
PYTHON

class Product(BaseModel):
    category: str = Field(..., discriminator="product_category")


class Book(Product):
    product_category: Literal["book"] = "book"
    author: str
    pages: int


class EBook(Book):
    format: str = Field(..., discriminator="file_format")


class PDF(EBook):
    file_format: Literal["pdf"] = "pdf"
    dpi: int


class EPUB(EBook):
    file_format: Literal["epub"] = "epub"
    reflowable: bool

3.2 交叉类型鉴别
PYTHON

from pydantic import validator


class Media(BaseModel):
    media_type: str = Field(..., discriminator="media_kind")
    content_type: str = Field(..., discriminator="mime_type")


class Video(Media):
    media_kind: Literal["video"] = "video"
    mime_type: Literal["video/mp4"] = "video/mp4"
    resolution: str


# 自动处理双鉴别字段
data = {
    "media_type": "video",
    "mime_type": "video/mp4",
    "resolution": "1080p"
}
media = Media.parse_obj(data)  # 精确匹配Video类型

第四章:企业级应用模式
4.1 API响应标准化
PYTHON

class ApiResponse(BaseModel):
    status: Literal["success", "error"]
    data: Union[UserResponse, ErrorResponse] = Field(...,
                                                     discriminator="response_type"
                                                     )


class UserResponse(BaseModel):
    response_type: Literal["user"] = "user"
    id: int
    name: str


class ErrorResponse(BaseModel):
    response_type: Literal["error"] = "error"
    code: int
    message: str

4.2 消息队列集成
PYTHON

class KafkaMessage(BaseModel):
    event_type: str = Field(..., discriminator="event_category")
    timestamp: datetime = Field(default_factory=datetime.now)


class OrderCreated(KafkaMessage):
    event_category: Literal["order_created"] = "order_created"
    order_id: str
    amount: float


class PaymentFailed(KafkaMessage):
    event_category: Literal["payment_failed"] = "payment_failed"
    error_code: int
    retry_count: int

第五章:错误处理与优化
5.1 错误类型分析
PYTHON

try:
    Animal.parse_obj({"_type": "fish"})
except ValidationError as e:
    print(e.json())
    """
    [
      {
        "loc": ["_type"],
        "msg": "No match for discriminator 'animal_type' 
                and value 'fish'",
        "type": "value_error.discriminator.not_found"
      }
    ]
    """

5.2 性能优化策略
PYTHON

from pydantic import BaseModel, ConfigDict


class OptimizedModel(BaseModel):
    model_config = ConfigDict(
        from_attributes=True,
        revalidate_instances="always"
    )
    __slots__ = ("__weakref__",)  # 减少内存占用

课后Quiz
Q1:鉴别器字段必须满足什么条件?
A) 在所有子模型中存在
B) 必须是唯一值
C) 需要继承父类字段

Q2:处理未知类型的正确方式?

扩展Union类型
添加默认处理
抛出ValidationError
Q3:优化解析性能的最佳实践?

启用模型缓存
增加字段校验
使用动态导入
错误解决方案速查表

错误信息 原因分析 解决方案
discriminator.not_found 未注册子模型类型 更新Union联合类型定义
value_error.union.invalid 类型匹配顺序错误 调整Union类型顺序
validation_error.missing 鉴别器字段缺失 添加必需鉴别字段
type_error.invalid_generic 动态模型未正确注册 使用create_model显式创建
架构原则:多态模型设计应符合OCP(开闭原则),新增类型时只需扩展Union类型而无需修改现有解析逻辑。建议为每个业务领域建立独立的鉴别器命名空间,避免全局类型冲突。    

来源:https://blog.cmdragon.cn/posts/4ab129859b04/


相关教程