Pydantic 的类型提示为数据验证提供了坚实的支持,能够自动检查输入数据是否与 int、float 或 str 等预期类型匹配,但应用程序通常需要更细致的控制。例如,您可能需要确保数值输入在特定范围内,字符串满足特定的长度要求,或者列表包含准确数量的元素。在这种情况下,Pydantic 的数据转换功能和约束定义就显得非常有用了。自动数据转换Pydantic 的一个实用特点是它会尝试将输入数据自动转换为您在模型中指定的类型。例如,如果您的 API 期望一个整数但收到了字符串 "123",Pydantic 通常能成功将其转换为整数 123。请看这个简单模型:from pydantic import BaseModel class Item(BaseModel): item_id: int name: str price: float is_offer: bool | None = None # 允许布尔值或 None如果您的 FastAPI 端点收到如下 JSON 有效负载:{ "item_id": "42", "name": "Example Item", "price": "99.95", "is_offer": "true" }Pydantic 将解析此数据并转换值:"42" 变为整数 42。"99.95" 变为浮点数 99.95。"true" 变为布尔值 True。这种自动转换简化了处理 Web 请求中常见的数据格式。但是,请谨慎使用此功能。如果转换失败(例如,尝试将 "abc" 转换为整数),Pydantic 将引发验证错误,FastAPI 会自动将其转换为一条有用的 HTTP 错误响应返回给客户端。使用 Field 定义明确约束为了更精确的验证规则,Pydantic 提供了 Field 函数。在 BaseModel 中定义属性时,您可以使用 Field 作为默认值,这样就能指定各种约束。我们来看看机器学习输入中常用的约束。数值约束处理数值特征时,您通常需要限制它们的取值范围。Field 为此提供了几个参数:gt: 大于ge: 大于或等于lt: 小于le: 小于或等于from pydantic import BaseModel, Field class ModelInput(BaseModel): # 特征必须是正数 feature1: float = Field(..., gt=0) # 概率必须在 0 到 1 之间(包括两端) probability_threshold: float = Field(..., ge=0, le=1) # 在特定范围内的整数特征 count_feature: int = Field(..., ge=0, le=100)在这里,...(省略号)表示该字段是必需的。如果您提供默认值而不是 ...,则该字段变为可选。使用这些约束可以确保在数据到达模型预测逻辑之前,就能拒绝不合理的值(例如负概率或计数)。字符串约束文本输入也经常能从约束中受益:min_length: 最小字符串长度max_length: 最大字符串长度pattern: 字符串必须匹配的正则表达式from pydantic import BaseModel, Field import re # 导入正则表达式模块 class UserProfile(BaseModel): username: str = Field(..., min_length=3, max_length=50) # 确保用户 ID 遵循特定格式(例如,以 'UID' 开头,后跟数字) user_id: str = Field(..., pattern=r"^UID\d+$") # 可选的个人简介,有最大长度限制 bio: str | None = Field(default=None, max_length=250)正则表达式模式 (pattern) 对于验证结构化标识符或数据预处理步骤中常见的特定文本格式特别有用。集合约束对于表示为列表或其他集合(如特征向量)的特征,您可能需要强制执行大小限制:min_items: 集合中的最小项数max_items: 集合中的最大项数from pydantic import BaseModel, Field class EmbeddingInput(BaseModel): # 期望一个 128 个浮点数的固定大小向量 vector: list[float] = Field(..., min_items=128, max_items=128) # 标签列表,必须至少有一个标签,最多 10 个 tags: list[str] = Field(..., min_items=1, max_items=10)这对于许多期望特定维度输入向量的 ML 模型来说是很重要的。尽早验证大小可以防止模型推理期间的运行时错误。实践中应用约束我们将这些特性组合到一个 Pydantic 模型中,该模型旨在验证房价预测模型的输入。from pydantic import BaseModel, Field class HouseFeatures(BaseModel): area_sqft: float = Field( ..., gt=0, description="房屋的表面积(平方英尺)。", example=1500.50 ) bedrooms: int = Field( ..., ge=1, le=10, description="卧室数量。", example=3 ) year_built: int = Field( ..., gt=1800, lt=2025, # 假设当前年份环境 description="房屋建造年份。", example=1995 ) zip_code: str = Field( ..., pattern=r"^\d{5}$", # 美国 5 位邮政编码格式 description="美国 5 位邮政编码。", example="90210" ) # FastAPI 端点中的使用示例 # from fastapi import FastAPI # app = FastAPI() # @app.post("/predict_price/") # async def predict_house_price(features: HouseFeatures): # # 此时,'features' 保证根据 HouseFeatures 中定义的约束是有效的。 # # 继续进行模型预测... # prediction = ... # 您的模型.predict([[features.area_sqft, ...]]) # return {"predicted_price": prediction} 如果客户端向 /predict_price/ 发送的数据违反了任何这些约束(例如,bedrooms: 0、area_sqft: -100 或 zip_code: "abcde"),由 Pydantic 提供支持的 FastAPI 将自动返回 422 Unprocessable Entity 错误响应。此响应会详细说明哪些字段未能通过验证以及原因,从而为 API 调用者提供明确的反馈。通过运用 Pydantic 的 Field 函数进行数据转换和约束,您可以将验证逻辑从端点函数中移出,放到声明式、可重用的模型中。这使得 API 代码更简洁,提高了对无效数据的健壮性,并通过在最早阶段捕获错误,更好地遵循了“快速失败”的原则。这保证了到达您的 ML 模型推理代码的数据已根据您定义的规则通过了正确性验证。