Pydantic 模型

发布于:2025-06-28 ⋅ 阅读:(16) ⋅ 点赞:(0)

本文将详细介绍 Pydantic 模型BaseModel 的核心概念,并通过实际代码示例如何从零开始编写自己的 Pydantic 模型。


1. Pydantic 是什么?

Pydantic 是一个 Python 库,主要用于:

  • 数据验证:确保输入数据符合预期的类型和约束。
  • 数据解析:将 JSON、字典等原始数据转换为 Python 对象。
  • 文档生成:自动生成 API 文档(如 Swagger/OpenAPI)。
  • 配置管理:安全地加载环境变量或配置文件。

2. BaseModel:所有模型的基类

Pydantic 的所有模型都继承自 BaseModel。它提供了核心功能:

  • 自动验证字段类型。
  • 支持默认值和可选字段。
  • 生成 JSON Schema(用于 API 文档)。

基础示例

from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

# 使用字典初始化
user_data = {"name": "Alice", "age": 25}
user = User(**user_data)  # 自动验证字段类型

print(user.name)  # 输出: Alice
print(user.age)   # 输出: 25

3. 如何编写自己的 Pydantic 模型?

(1) 定义字段类型

Pydantic 支持 Python 原生类型和复杂类型:

from typing import Optional, List
from datetime import datetime
import uuid

class Product(BaseModel):
    id: uuid.UUID                  # UUID 类型
    name: str                      # 必填字符串
    price: float                   # 浮点数
    tags: List[str]                # 字符串列表
    created_at: datetime           # 日期时间
    discount: Optional[float] = None  # 可选字段

(2) 添加字段约束

使用 Field 定义更复杂的规则:

from pydantic import BaseModel, Field

class User(BaseModel):
    username: str = Field(..., min_length=3, max_length=20)  # 必填,长度3-20
    email: str = Field(..., regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
    age: int = Field(ge=18, description="必须成年")  # 年龄 ≥ 18

(3) 自定义验证逻辑

通过 @validator 添加自定义验证:

from pydantic import validator

class Payment(BaseModel):
    amount: float
    currency: str

    @validator("amount")
    def amount_must_be_positive(cls, v):
        if v <= 0:
            raise ValueError("金额必须大于0")
        return v

    @validator("currency")
    def currency_must_be_valid(cls, v):
        if v not in ["USD", "EUR", "JPY"]:
            raise ValueError("无效的货币类型")
        return v

(4) 嵌套模型

模型可以嵌套其他模型:

class Address(BaseModel):
    city: str
    street: str

class Person(BaseModel):
    name: str
    address: Address  # 嵌套模型

# 使用示例
data = {
    "name": "Bob",
    "address": {"city": "New York", "street": "5th Ave"}
}
person = Person(**data)

4. 高级用法

(1) 配置模型行为

通过 Config 类自定义模型行为:

class ConfigExample(BaseModel):
    name: str

    class Config:
        anystr_strip_whitespace = True  # 自动去除字符串两端空格
        allow_population_by_field_name = True  # 允许用别名初始化
        extra = "forbid"  # 禁止额外字段

(2) 生成 JSON Schema

Pydantic 自动为模型生成 JSON Schema:

print(User.schema_json(indent=2))

输出:

{
  "title": "User",
  "type": "object",
  "properties": {
    "username": {
      "type": "string",
      "minLength": 3,
      "maxLength": 20
    },
    "email": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
    },
    "age": {
      "type": "integer",
      "minimum": 18,
      "description": "必须成年"
    }
  },
  "required": ["username", "email", "age"]
}

(3) 与环境变量集成

从环境变量加载配置:

from pydantic import BaseSettings

class Settings(BaseSettings):
    api_key: str
    debug: bool = False

    class Config:
        env_file = ".env"  # 从.env文件加载

settings = Settings()  # 自动读取环境变量

5. 完整示例:用户注册 API 模型

from pydantic import BaseModel, Field, EmailStr, validator
from typing import Optional
from datetime import datetime

class UserRegister(BaseModel):
    username: str = Field(..., min_length=3, max_length=20)
    email: EmailStr  # 专门验证邮箱格式的类型
    password: str = Field(..., min_length=8)
    birth_date: Optional[datetime] = None
    referral_code: Optional[str] = Field(None, max_length=10)

    @validator("password")
    def password_must_contain_special_char(cls, v):
        if not any(c in "!@#$%^&*" for c in v):
            raise ValueError("密码必须包含特殊字符")
        return v

# 使用示例
user_data = {
    "username": "alice123",
    "email": "alice@example.com",
    "password": "secure!123"
}
user = UserRegister(**user_data)  # 自动验证

6. 常见问题解答

Q1:Pydantic 和 Dataclasses 有什么区别?

  • Pydantic:专注于数据验证和解析,支持复杂约束(如正则、自定义验证)。
  • Dataclasses:仅生成 __init____repr__,无验证功能。

Q2:如何处理未知字段?

通过 Config 控制:

class Config:
    extra = "allow"   # 允许额外字段(默认)
    extra = "forbid"  # 禁止额外字段
    extra = "ignore"  # 忽略额外字段

Q3:性能如何?

Pydantic 在首次运行时会生成验证逻辑的优化代码,后续调用速度接近原生 Python。


总结

功能 实现方式
基础字段定义 name: str
字段约束 Field(..., min_length=3)
自定义验证 @validator 装饰器
嵌套模型 直接嵌套其他 BaseModel
环境变量集成 继承 BaseSettings + Config
生成 API 文档 自动通过 schema_json() 或 FastAPI 集成

通过 Pydantic,你可以用极少的代码实现强大的数据验证和转换逻辑,非常适合 API 开发、配置管理和数据处理场景。


网站公告

今日签到

点亮在社区的每一天
去签到