Python 数据校验神器:Pydantic 完全指南

在 Python 后端开发中,我们经常会遇到这样的问题:

  • API 参数类型不正确
  • JSON 数据结构混乱
  • 配置文件字段缺失
  • 数据转换逻辑到处都是
  • 手动写 dict.get()isinstance()

例如:

data = {
    "name": "Tom",
    "age": "18"
}

这里 age 明明应该是整数,但却是字符串。

传统做法:

age = int(data["age"])

项目一大,这种转换代码会遍布整个系统。

而这正是 Pydantic 的核心价值:

用 Python 类型注解,自动完成:

  • 数据校验
  • 类型转换
  • JSON 解析
  • 配置管理
  • 数据序列化

如今:

  • FastAPI
  • LangChain
  • OpenAI SDK
  • SQLModel
  • Settings 管理系统

都大量依赖 Pydantic。


一、什么是 Pydantic

Pydantic 是一个:

基于 Python Type Hint 的数据校验与数据建模库

官网:

Pydantic 官方网站

GitHub:

Pydantic GitHub 仓库

核心理念:

from pydantic import BaseModel

使用 Python 类型定义数据结构:

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

然后:

user = User(
    name="Tom",
    age="18"
)

Pydantic 会自动:

age -> int(18)

最终:

User(name='Tom', age=18)

二、Pydantic 能解决什么问题

1)数据校验(Validation)

自动检查字段是否合法:

from pydantic import BaseModel

class User(BaseModel):
    age: int

User(age="abc")

输出:

ValidationError:
value is not a valid integer

2)自动类型转换(Parsing)

class User(BaseModel):
    age: int

u = User(age="18")

print(u.age)

输出:

18

类型:

int

3)结构化数据建模

复杂 JSON:

{
  "user": {
    "name": "Tom",
    "age": 18
  }
}

对应:

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

class Response(BaseModel):
    user: User

自动嵌套解析。


4)序列化 JSON

user.model_dump()

输出:

{
    "name": "Tom",
    "age": 18
}

JSON:

user.model_dump_json()

5)配置管理

Pydantic 还能管理环境变量:

DATABASE_URL=postgresql://...

自动映射为:

class Settings(BaseSettings):
    database_url: str

这是现代 Python 项目常见做法。


三、安装 Pydantic

安装最新版:

pip install pydantic

如果需要 Settings:

pip install pydantic-settings

(补充):pydantic 和 pydantic-settings 的区别

  • pydantic:核心库,用于通用数据验证(比如验证 API 请求体)。
  • pydantic-settings专注于应用配置管理,是对 pydantic 的扩展(底层仍用 Pydantic 的验证逻辑)。

💡 简单说:

  • 如果你需要验证用户输入 → 用 pydantic
  • 如果你需要管理应用配置 → 用 pydantic-settings

四、BaseModel 核心机制

Pydantic 的核心就是:

BaseModel

例如:

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    stock: int

创建对象:

p = Product(
    name="iPhone",
    price="5999",
    stock="10"
)

print(p)

输出:

name='iPhone' price=5999.0 stock=10

注意:

  • 自动类型转换
  • 自动校验
  • 自动生成对象

(补充)BaseModel

BaseModel 是 Pydantic 库的核心基类,用于定义结构化的数据模型。它的核心作用是为 Python 类提供自动数据验证、类型转换和序列化能力。

五、字段类型支持

Pydantic 支持大量 Python 类型。


基础类型

class User(BaseModel):
    name: str
    age: int
    score: float
    active: bool

列表

from typing import List

class User(BaseModel):
    tags: List[str]

字典

from typing import Dict

class Config(BaseModel):
    headers: Dict[str, str]

Optional

from typing import Optional

class User(BaseModel):
    nickname: Optional[str] = None

Union

from typing import Union

class Item(BaseModel):
    value: Union[int, str]

枚举 Enum

from enum import Enum

class Role(str, Enum):
    admin = "admin"
    user = "user"

class Account(BaseModel):
    role: Role

六、字段约束(Field)

Pydantic 提供:

Field()

用于定义:

  • 默认值
  • 范围限制
  • 描述信息
  • 长度限制

例如:

from pydantic import BaseModel, Field

class User(BaseModel):
    username: str = Field(
        min_length=3,
        max_length=20
    )

    age: int = Field(
        ge=0,
        le=150
    )

常见约束

参数 含义
gt 大于
ge 大于等于
lt 小于
le 小于等于
min_length 最小长度
max_length 最大长度
pattern 正则匹配

七、自定义校验器(Validator)

有时候:

类型正确 ≠ 数据合法。

例如:

username="admin"

你可能不允许。


Pydantic v2 写法

from pydantic import BaseModel, field_validator

class User(BaseModel):
    username: str

    @field_validator("username")
    @classmethod
    def validate_username(cls, v):
        if v == "admin":
            raise ValueError("reserved username")
        return v

八、模型嵌套(Nested Model)

复杂 API 非常常见。

例如:

{
  "id": 1,
  "user": {
    "name": "Tom"
  }
}

模型:

class User(BaseModel):
    name: str

class Order(BaseModel):
    id: int
    user: User

Pydantic 自动递归解析。


九、模型序列化

Pydantic v2:

model_dump()

替代旧版:

dict()

例如:

user.model_dump()

JSON:

user.model_dump_json()

十、Alias(字段别名)

很多 API 使用:

{
  "user_name": "Tom"
}

但 Python 喜欢:

user_name

或者:

username

Pydantic 支持字段映射:

from pydantic import Field

class User(BaseModel):
    username: str = Field(alias="user_name")

十一、严格模式(Strict Mode)

默认情况下:

age="18"

会自动转成:

18

但有时你不想自动转换。


Strict 类型

from pydantic import StrictInt

class User(BaseModel):
    age: StrictInt

此时:

age="18"

会报错。


十二、Settings 配置管理

现代 Python 项目中:

环境变量配置非常重要。


安装

pip install pydantic-settings

示例

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    app_name: str
    database_url: str

settings = Settings()

环境变量:

export APP_NAME=myapp
export DATABASE_URL=postgresql://localhost/db

自动读取。


十三、Pydantic 与 FastAPI

FastAPI 与 Pydantic 深度绑定。

例如:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

@app.post("/users")
def create_user(user: User):
    return user

FastAPI 自动:

  • 校验请求
  • 解析 JSON
  • 生成 OpenAPI
  • 生成 Swagger 文档

这是 FastAPI 强大的关键之一。


十四、Pydantic v1 vs v2

Pydantic v2 是一次重大升级。


v2 的变化

1)性能更快

底层改为:

pydantic-core (Rust)

速度大幅提升。


2)API 变化

v1:

dict()
json()

v2:

model_dump()
model_dump_json()

3)Validator 变化

v1:

@validator

v2:

@field_validator

十五、Pydantic 的底层原理

Pydantic 本质上:

Python Type Hint
        ↓
生成 Schema
        ↓
校验输入数据
        ↓
转换 Python 对象

v2 使用:

pydantic-core

底层 Rust 引擎负责:

  • 高性能解析
  • 类型校验
  • JSON 处理

因此性能非常优秀。


十六、典型应用场景


Web API

FastAPI 请求体:

class Request(BaseModel):
    ...

AI Agent / LLM

LangChain/OpenAI:

Structured Output

大量使用 Pydantic。


配置管理

.env
环境变量

数据 ETL(Extract、Transform、Load)

解析:

  • JSON
  • YAML
  • Kafka 消息
  • MQ 数据

ORM 边界层

数据库对象 → API 输出对象。


十七、为什么 Pydantic 如此流行

核心原因:


1)类型即文档

age: int

既是:

  • 类型定义
  • 校验规则
  • IDE 提示
  • 文档

2)减少样板代码

不再需要:

if not isinstance(...)

3)与现代 Python 高度契合

充分利用:

  • Type Hint
  • Dataclass 思想
  • IDE 类型系统

4)FastAPI 带来的生态爆发

FastAPI 的流行直接推动了 Pydantic。


十八、Pydantic 的局限性

虽然强大,但也有注意点。


1)隐式类型转换可能危险

"18" -> 18

有时可能隐藏 Bug。

建议关键场景使用:

StrictInt

2)复杂模型可能影响性能

虽然 v2 已经很快:

但超大型嵌套模型仍有开销。


3)学习成本来自类型系统

如果不熟悉:

  • Type Hint
  • 泛型
  • Optional
  • Union

会有门槛。


十九、最佳实践


推荐

使用 v2

新项目建议直接:

pip install pydantic>=2

所有 API 输入都使用 BaseModel

避免裸 dict。


关键字段使用 Strict 类型

尤其:

  • 金额
  • 权限
  • ID

使用 model_dump()

不要再使用旧版:

dict()

二十、总结

Pydantic 本质上是:

Python 世界的数据契约系统(Data Contract System)

它把:

类型定义
+
数据校验
+
数据解析
+
JSON 序列化

统一到了:

class Model(BaseModel):

之中。

现代 Python 开发中:

  • FastAPI
  • AI Agent
  • LLM Structured Output
  • 配置管理
  • 微服务 API

几乎都离不开 Pydantic。

如果你正在:

  • 写 API
  • 写 AI 系统
  • 写数据处理系统
  • 写配置系统

那么 Pydantic 基本已经成为必备技能。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐