Pydantic 完全指南:Python 数据校验与序列化
Pydantic 是 Python 数据校验库:模型定义、字段约束、自定义校验器、序列化转换与 JSON Schema 生成。本文系统讲解 Pydantic 的核心与进阶用法。
直接回答:Pydantic 在构造或显式校验模型时执行校验;默认可能转换类型,并非全程序自动强类型:数据不符合模型定义就抛出清晰的错误。模型即 Schema,校验、解析、序列化、文档生成四合一——FastAPI 的基石,Python 数据处理的事实标准。
为什么是 Pydantic
Python 类型注解本身不自动校验外部输入,Pydantic 提供显式模型校验。v2 使用 Rust 编写的 pydantic-core;性能收益取决于模型和校验逻辑,本文未进行基准测试。
定义模型
from pydantic import BaseModel, ConfigDict
class User(BaseModel):
name: str
email: str
age: int = 18 # 默认值
tags: list[str] = [] # 可变默认安全处理
user = User(name="张三", email="zs@example.com", age="28") # "28" 自动转 int
注意 age="28" 也被接受——Pydantic 默认做智能类型强制转换(字符串数字 → 数字)。要严格模式(拒绝转换)开 model_config = ConfigDict(strict=True)。
字段约束
from pydantic import Field, EmailStr, HttpUrl
class Product(BaseModel):
name: str = Field(min_length=1, max_length=100)
price: float = Field(gt=0, description="必须为正数")
sku: str = Field(pattern=r"^[A-Z]{2}-\d{4}$")
contact: EmailStr # 合法邮箱
website: HttpUrl | None = None
stock: int = Field(default=0, ge=0)
EmailStr 需安装 email-validator(可用 pip install 'pydantic[email]');内置类型覆盖邮箱、URL、UUID、日期时间、路径等;约束即文档——Field(description=...) 会进 JSON Schema。
自定义校验器
from pydantic import field_validator, model_validator
class Order(BaseModel):
quantity: int
unit_price: float
discount_code: str | None = None
@field_validator("quantity")
@classmethod
def quantity_positive(cls, v):
if v <= 0:
raise ValueError("数量必须为正")
return v
@model_validator(mode="after")
def check_discount(self):
if self.discount_code and self.unit_price < 10:
raise ValueError("低价商品不可用优惠券")
return self
字段级用 field_validator,跨字段用 model_validator——业务规则就这样住进了数据结构。
序列化与转换
user.model_dump() # 字典
user.model_dump_json() # JSON 字符串
user.model_dump(exclude={"tags"}) # 排除字段
user.model_dump(by_alias=True) # 按别名输出(对接外部 API 命名)
User.model_validate(raw_dict) # 校验并构造
别名机制(Field(alias="userName"))让 Python 的蛇形命名与外部系统的驼峰命名和平共处。
JSON Schema 自动生成
print(Product.model_json_schema())
一份模型定义同时产出:运行校验 + 文档 Schema + 前端表单生成依据。FastAPI 的自动文档、marshmallow 替代的底气都源于此。
常见问题(FAQ)
Q:v1 和 v2 差异大吗?
A:大。validator 改名 field_validator、.dict() 改 .model_dump()、ORM 模式改 from_attributes。老项目迁移看官方迁移指南,新项目直接 v2。
Q:严格模式该不该开?
A:对外部输入(表单、第三方 webhook)应根据输入协议决定是否允许转换,不宜一律使用宽松模式("42"→42);对内部关键数据(金额、状态机)开 strict 防静默转换。
Q:性能敏感场景注意什么?
A:v2 已经很快;热点路径上注意:复用模型类、避免不必要的深嵌套、大批量场景可考虑 msgspec 对比基准。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。