|
| 1 | +Pydantic 是一个流行的 Python 库,主要用于数据验证和序列化。它基于 Python 的类型注解(`typing` 模块),提供了一种优雅的方式来定义数据模型、验证输入数据,并在必要时将其转换为指定类型。Pydantic 被广泛应用于 Web 开发(例如 FastAPI)、配置文件解析以及任何需要处理结构化数据的场景。 |
| 2 | + |
| 3 | +以下是对 Pydantic 的详细介绍: |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +### 1. **基本概念** |
| 8 | +Pydantic 的核心是 `BaseModel` 类,通过继承它,你可以定义一个数据模型。模型中的字段使用类型注解来声明,Pydantic 会根据这些注解自动验证和转换数据。 |
| 9 | + |
| 10 | +安装 Pydantic: |
| 11 | + |
| 12 | +```bash |
| 13 | +pip install pydantic |
| 14 | +``` |
| 15 | + |
| 16 | +简单示例: |
| 17 | + |
| 18 | +```python |
| 19 | +from pydantic import BaseModel |
| 20 | + |
| 21 | +class User(BaseModel): |
| 22 | + id: int |
| 23 | + name: str |
| 24 | + age: int |
| 25 | + |
| 26 | +# 创建实例 |
| 27 | +user = User(id=1, name="Alice", age=25) |
| 28 | +print(user) # 输出: id=1 name='Alice' age=25 |
| 29 | + |
| 30 | +# 数据验证 |
| 31 | +invalid_user = User(id="not_an_int", name="Bob", age=30) # 抛出 ValidationError |
| 32 | +``` |
| 33 | + |
| 34 | +在这个例子中: |
| 35 | + |
| 36 | ++ 如果 `id` 不是整数,Pydantic 会抛出 `ValidationError`。 |
| 37 | ++ Pydantic 会自动将输入数据解析为指定类型(例如,字符串 `"1"` 可以转换为整数 `1`)。 |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +### 2. **核心特性** |
| 42 | +#### 数据验证 |
| 43 | +Pydantic 会检查字段是否符合声明的类型,并支持复杂的验证规则。例如: |
| 44 | + |
| 45 | +```python |
| 46 | +from pydantic import BaseModel, EmailStr, PositiveInt |
| 47 | + |
| 48 | +class Person(BaseModel): |
| 49 | + name: str |
| 50 | + email: EmailStr # 验证邮箱格式 |
| 51 | + age: PositiveInt # 必须是正整数 |
| 52 | + |
| 53 | +person = Person(name="Alice", email="alice@example.com", age=25) |
| 54 | +print(person) # 输出: name='Alice' email='alice@example.com' age=25 |
| 55 | + |
| 56 | +# 无效数据会报错 |
| 57 | +person = Person(name="Bob", email="invalid-email", age=-5) # 抛出 ValidationError |
| 58 | +``` |
| 59 | + |
| 60 | +#### 数据转换 |
| 61 | +Pydantic 不仅验证数据,还会尝试将输入转换为目标类型: |
| 62 | + |
| 63 | +```python |
| 64 | +user = User(id="1", name="Alice", age="25") # 字符串会被转换为 int |
| 65 | +print(user.id, type(user.id)) # 输出: 1 <class 'int'> |
| 66 | +``` |
| 67 | + |
| 68 | +#### 嵌套模型 |
| 69 | +支持定义嵌套的数据结构: |
| 70 | + |
| 71 | +```python |
| 72 | +from pydantic import BaseModel |
| 73 | + |
| 74 | +class Address(BaseModel): |
| 75 | + city: str |
| 76 | + country: str |
| 77 | + |
| 78 | +class User(BaseModel): |
| 79 | + name: str |
| 80 | + address: Address |
| 81 | + |
| 82 | +user = User(name="Alice", address={"city": "Beijing", "country": "China"}) |
| 83 | +print(user) # 输出: name='Alice' address=Address(city='Beijing', country='China') |
| 84 | +``` |
| 85 | + |
| 86 | +#### 默认值和可选字段 |
| 87 | +可以使用 `Optional` 或默认值: |
| 88 | + |
| 89 | +```python |
| 90 | +from typing import Optional |
| 91 | +from pydantic import BaseModel |
| 92 | + |
| 93 | +class User(BaseModel): |
| 94 | + id: int |
| 95 | + name: str = "Anonymous" # 默认值 |
| 96 | + email: Optional[str] = None # 可选字段 |
| 97 | + |
| 98 | +user = User(id=1) |
| 99 | +print(user) # 输出: id=1 name='Anonymous' email=None |
| 100 | +``` |
| 101 | + |
| 102 | +#### 序列化 |
| 103 | +Pydantic 模型可以轻松转换为 JSON 或字典: |
| 104 | + |
| 105 | +```python |
| 106 | +print(user.dict()) # 输出: {'id': 1, 'name': 'Anonymous', 'email': None} |
| 107 | +print(user.json()) # 输出: {"id": 1, "name": "Anonymous", "email": null} |
| 108 | +``` |
| 109 | + |
| 110 | +--- |
| 111 | + |
| 112 | +### 3. **高级功能** |
| 113 | +#### 自定义验证 |
| 114 | +通过 `@validator` 装饰器,可以为字段添加自定义验证逻辑: |
| 115 | + |
| 116 | +```python |
| 117 | +from pydantic import BaseModel, validator |
| 118 | + |
| 119 | +class User(BaseModel): |
| 120 | + username: str |
| 121 | + password: str |
| 122 | + |
| 123 | + @validator("password") |
| 124 | + def password_must_be_strong(cls, v): |
| 125 | + if len(v) < 8: |
| 126 | + raise ValueError("Password must be at least 8 characters") |
| 127 | + return v |
| 128 | + |
| 129 | +user = User(username="alice", password="12345678") # 通过 |
| 130 | +invalid = User(username="bob", password="weak") # 抛出 ValidationError |
| 131 | +``` |
| 132 | + |
| 133 | +#### 配置类 |
| 134 | +通过 `Config` 类调整模型行为,例如字段别名、忽略额外字段等: |
| 135 | + |
| 136 | +```python |
| 137 | +class User(BaseModel): |
| 138 | + id: int |
| 139 | + full_name: str |
| 140 | + |
| 141 | + class Config: |
| 142 | + fields = {"full_name": "name"} # 别名映射 |
| 143 | + |
| 144 | +user = User(id=1, name="Alice") # 使用别名 "name" 传入数据 |
| 145 | +print(user.full_name) # 输出: Alice |
| 146 | +``` |
| 147 | + |
| 148 | +#### 环境变量和 Settings |
| 149 | +Pydantic 提供 `BaseSettings` 来管理配置,例如从环境变量加载数据: |
| 150 | + |
| 151 | +```python |
| 152 | +from pydantic import BaseSettings |
| 153 | + |
| 154 | +class Settings(BaseSettings): |
| 155 | + api_key: str |
| 156 | + database_url: str |
| 157 | + |
| 158 | + class Config: |
| 159 | + env_prefix = "MYAPP_" # 环境变量前缀 |
| 160 | + |
| 161 | +settings = Settings() # 自动从环境变量 MYAPP_API_KEY 和 MYAPP_DATABASE_URL 加载 |
| 162 | +``` |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +### 4. **与 FastAPI 的结合** |
| 167 | +Pydantic 是 FastAPI 的核心组件,用于定义 API 的请求和响应模型。例如: |
| 168 | + |
| 169 | +```python |
| 170 | +from fastapi import FastAPI |
| 171 | +from pydantic import BaseModel |
| 172 | + |
| 173 | +app = FastAPI() |
| 174 | + |
| 175 | +class Item(BaseModel): |
| 176 | + name: str |
| 177 | + price: float |
| 178 | + |
| 179 | +@app.post("/items/") |
| 180 | +async def create_item(item: Item): |
| 181 | + return item |
| 182 | +``` |
| 183 | + |
| 184 | ++ FastAPI 会自动验证请求体的数据,并返回符合 `Item` 模型的响应。 |
| 185 | ++ 如果数据不合法,会返回详细的错误信息。 |
| 186 | + |
| 187 | +--- |
| 188 | + |
| 189 | +### 5. **优势** |
| 190 | ++ **类型安全**: 结合类型注解,确保数据符合预期。 |
| 191 | ++ **开发效率**: 自动验证和转换减少了手动检查代码。 |
| 192 | ++ **可读性**: 数据模型定义清晰,易于理解。 |
| 193 | ++ **生态支持**: 与 FastAPI、SQLAlchemy 等库无缝集成。 |
| 194 | + |
| 195 | +--- |
| 196 | + |
| 197 | +### 6. **局限性** |
| 198 | ++ **性能开销**: 验证和转换会带来少量运行时开销,不适合极高性能场景。 |
| 199 | ++ **学习曲线**: 对于新手来说,自定义验证和复杂嵌套模型可能需要时间适应。 |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +### 7. **版本演进** |
| 204 | ++ **Pydantic V1**: 稳定版本,广泛使用。 |
| 205 | ++ **Pydantic V2**(2023 年发布):性能大幅提升,支持更多功能(如更快的 JSON 序列化),但 API 有部分变化。建议查看官方文档以了解迁移指南。 |
| 206 | + |
| 207 | +安装 V2: |
| 208 | + |
| 209 | +```bash |
| 210 | +pip install pydantic>=2.0 |
| 211 | +``` |
| 212 | + |
| 213 | +--- |
| 214 | + |
| 215 | +### 总结 |
| 216 | +Pydantic 是一个强大而灵活的工具,特别适合需要处理外部输入数据(如 API 请求、配置文件)的场景。它通过类型注解和验证机制,将 Python 的动态特性与静态类型检查的优势结合在一起。 |
| 217 | + |
0 commit comments