Pydantic 是一个流行的 Python 库,主要用于数据验证和序列化。它基于 Python 的类型注解(typing
模块),提供了一种优雅的方式来定义数据模型、验证输入数据,并在必要时将其转换为指定类型。Pydantic 被广泛应用于 Web 开发(例如 FastAPI)、配置文件解析以及任何需要处理结构化数据的场景。
以下是对 Pydantic 的详细介绍:
1. 基本概念
Pydantic 的核心是 BaseModel
类,通过继承它,你可以定义一个数据模型。模型中的字段使用类型注解来声明,Pydantic 会根据这些注解自动验证和转换数据。
安装 Pydantic:
bash
pip install pydantic
简单示例:
python
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
age: int
# 创建实例
user = User(id=1, name="Alice", age=25)
print(user) # 输出: id=1 name='Alice' age=25
# 数据验证
invalid_user = User(id="not_an_int", name="Bob", age=30) # 抛出 ValidationError
在这个例子中:
- 如果
id
不是整数,Pydantic 会抛出ValidationError
。 - Pydantic 会自动将输入数据解析为指定类型(例如,字符串
"1"
可以转换为整数1
)。
2. 核心特性
数据验证
Pydantic 会检查字段是否符合声明的类型,并支持复杂的验证规则。例如:
python
from pydantic import BaseModel, EmailStr, PositiveInt
class Person(BaseModel):
name: str
email: EmailStr # 验证邮箱格式
age: PositiveInt # 必须是正整数
person = Person(name="Alice", email="alice@example.com", age=25)
print(person) # 输出: name='Alice' email='alice@example.com' age=25
# 无效数据会报错
person = Person(name="Bob", email="invalid-email", age=-5) # 抛出 ValidationError
数据转换
Pydantic 不仅验证数据,还会尝试将输入转换为目标类型:
python
user = User(id="1", name="Alice", age="25") # 字符串会被转换为 int
print(user.id, type(user.id)) # 输出: 1 <class 'int'>
嵌套模型
支持定义嵌套的数据结构:
python
from pydantic import BaseModel
class Address(BaseModel):
city: str
country: str
class User(BaseModel):
name: str
address: Address
user = User(name="Alice", address={"city": "Beijing", "country": "China"})
print(user) # 输出: name='Alice' address=Address(city='Beijing', country='China')
默认值和可选字段
可以使用 Optional
或默认值:
python
from typing import Optional
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "Anonymous" # 默认值
email: Optional[str] = None # 可选字段
user = User(id=1)
print(user) # 输出: id=1 name='Anonymous' email=None
序列化
Pydantic 模型可以轻松转换为 JSON 或字典:
python
print(user.dict()) # 输出: {'id': 1, 'name': 'Anonymous', 'email': None}
print(user.json()) # 输出: {"id": 1, "name": "Anonymous", "email": null}
3. 高级功能
自定义验证
通过 @validator
装饰器,可以为字段添加自定义验证逻辑:
python
from pydantic import BaseModel, validator
class User(BaseModel):
username: str
password: str
@validator("password")
def password_must_be_strong(cls, v):
if len(v) < 8:
raise ValueError("Password must be at least 8 characters")
return v
user = User(username="alice", password="12345678") # 通过
invalid = User(username="bob", password="weak") # 抛出 ValidationError
配置类
通过 Config
类调整模型行为,例如字段别名、忽略额外字段等:
python
class User(BaseModel):
id: int
full_name: str
class Config:
fields = {"full_name": "name"} # 别名映射
user = User(id=1, name="Alice") # 使用别名 "name" 传入数据
print(user.full_name) # 输出: Alice
环境变量和 Settings
Pydantic 提供 BaseSettings
来管理配置,例如从环境变量加载数据:
python
from pydantic import BaseSettings
class Settings(BaseSettings):
api_key: str
database_url: str
class Config:
env_prefix = "MYAPP_" # 环境变量前缀
settings = Settings() # 自动从环境变量 MYAPP_API_KEY 和 MYAPP_DATABASE_URL 加载
4. 与 FastAPI 的结合
Pydantic 是 FastAPI 的核心组件,用于定义 API 的请求和响应模型。例如:
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/")
async def create_item(item: Item):
return item
- FastAPI 会自动验证请求体的数据,并返回符合
Item
模型的响应。 - 如果数据不合法,会返回详细的错误信息。
5. 优势
- 类型安全: 结合类型注解,确保数据符合预期。
- 开发效率: 自动验证和转换减少了手动检查代码。
- 可读性: 数据模型定义清晰,易于理解。
- 生态支持: 与 FastAPI、SQLAlchemy 等库无缝集成。
6. 局限性
- 性能开销: 验证和转换会带来少量运行时开销,不适合极高性能场景。
- 学习曲线: 对于新手来说,自定义验证和复杂嵌套模型可能需要时间适应。
7. 版本演进
- Pydantic V1: 稳定版本,广泛使用。
- Pydantic V2(2023 年发布):性能大幅提升,支持更多功能(如更快的 JSON 序列化),但 API 有部分变化。建议查看官方文档以了解迁移指南。
安装 V2:
bash
pip install pydantic>=2.0
总结
Pydantic 是一个强大而灵活的工具,特别适合需要处理外部输入数据(如 API 请求、配置文件)的场景。它通过类型注解和验证机制,将 Python 的动态特性与静态类型检查的优势结合在一起。