Python中 Pydantic数据验证库

Pydantic 是 Python 中最流行的数据验证 的第三方库,,它提供了一种声明式的方式来定义数据模型,基于类型注解 工作,具有高性能(核心验证逻辑用 Rust 编写)和优秀的 IDE 集成。

一、类型注解与验证

Pydantic 的核心是声明式数据建模 。通过继承 BaseModel 并定义带类型注解的类属性来声明数据模型。Pydantic 会自动进行:

  1. 数据验证:确保数据符合声明的类型。

  2. 数据转换(Coercion):在可能的情况下,自动将输入数据转换为声明的类型。

  3. 序列化:将模型实例导出为字典或 JSON。

二、快速上手:基础使用

1. 安装与导入
复制代码
pip install pydantic

from datetime import datetime
from pydantic import BaseModel
from typing import Optional, Dict, List
2. 定义第一个模型

一个User模型,演示了不同类型的字段。

复制代码
class User(BaseModel):
    id: int                     # 必填字段,会尝试将 '1' 转为 1
    name: str = "Jane Doe"      # 有默认值,成为可选字段
    signup_ts: Optional[datetime] = None  # 可为空的 datetime
    tastes: Dict[str, int] = {} # 字典类型,值为正整数
3. 数据验证与实例化

实例化时传入数据,Pydantic 会自动进行类型转换和验证

复制代码
# 这是外部数据,比如来自 API 或配置文件
external_data = {
    'id': '123',                # 注意:这是字符串
    'signup_ts': '2024-10-01 12:00',  # 字符串日期
    'tastes': {
        'wine': 5,
        'cheese': 3,
    },
}

# 实例化模型,验证并转换数据
user = User(**external_data)

# 访问属性(已转换为正确的类型)
print(user.id)                 # 输出: 123 (int)
print(user.signup_ts)          # 输出: 2024-10-01 12:00:00 (datetime)
print(user.model_dump())       # 输出字典: {'id': 123, 'name': 'Jane Doe', ...}
4. 处理验证错误

当数据不符合规范时,Pydantic 会抛出 ValidationError 并提供清晰的错误信息。

复制代码
from pydantic import ValidationError

invalid_data = {
    'id': 'not_a_number',       # 无法转为 int
    'signup_ts': 'invalid_date', # 无法转为 datetime
}

try:
    user = User(**invalid_data)
except ValidationError as e:
    print(e.json()) # 打印结构化的错误报告

三、进阶功能:增强模型能力

1. 使用 Field 添加约束和描述

Field 函数可以给字段添加额外的验证规则(如长度、数值范围)和元数据。

复制代码
from pydantic import BaseModel, Field

class Product(BaseModel):
    name: str = Field(min_length=1, max_length=50, description="产品名称")
    price: float = Field(ge=0, le=9999.99, description="产品价格")
    stock: int = Field(default=0, ge=0, description="库存")

product = Product(name="Laptop", price=999.99)
print(product.model_dump()) # 输出: {'name': 'Laptop', 'price': 999.99, 'stock': 0}

备注 :这是 Pydantic 库的语法BaseModel 在底层自动生成了 __init__ 方法,所以不需要手动写。Field 是用于添加字段描述的,不影响类型本身。

Field 常用参数

参数 说明 示例
description 字段描述(用于文档) Field(description="用户姓名")
default 默认值 Field(default="未知")
min_length 字符串最小长度 Field(min_length=1)
max_length 字符串最大长度 Field(max_length=100)
ge 数值 ≥ Field(ge=0)
le 数值 ≤ Field(le=100)
example 示例值(用于文档) Field(example="张三")
2. 嵌套模型与复杂类型

Pydantic 模型可以无缝嵌套,轻松处理复杂的 JSON 数据。

复制代码
from typing import List

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

class Student(BaseModel):
    name: str
    age: int
    addresses: List[Address] # 嵌套模型列表

data = {
    'name': 'Alice',
    'age': 20,
    'addresses': [{'city': 'Beijing', 'street': 'Chang'an Ave'}]
}
student = Student(**data)
print(student.addresses[0].city) # 输出: Beijing
3. 自定义验证器

使用 @field_validator@model_validator 装饰器实现复杂的业务逻辑验证。

复制代码
from pydantic import BaseModel, field_validator

class Order(BaseModel):
    quantity: int
    price: float

    @field_validator('quantity')
    @classmethod
    def quantity_must_be_positive(cls, v: int) -> int:
        if v <= 0:
            raise ValueError('quantity must be greater than 0')
        return v

    @field_validator('price')
    @classmethod
    def price_must_be_positive(cls, v: float) -> float:
        if v <= 0:
            raise ValueError('price must be greater than 0')
        return v
4. 严格模式

默认情况下 Pydantic 是"宽松"的(lax mode),会尝试转换类型。可以通过 model_config 启用严格模式来禁止类型转换。

复制代码
from pydantic import BaseModel, ConfigDict

class StrictUser(BaseModel):
    model_config = ConfigDict(strict=True)
    id: int

# StrictUser(id='123') # 这会直接报错,因为输入的是字符串,而 strict=True

四、总结

特性 说明 使用场景
数据验证 通过类型注解和Field自动完成。 验证API请求、配置文件、环境变量。
类型转换 智能将"1"转为1"2024-10-01"转为datetime 处理来自HTTP查询参数或字符串配置的数据。
序列化 .model_dump().model_dump_json() 方法。 将模型数据输出到数据库或响应API。
嵌套模型 模型可作为字段类型,完美对应复杂JSON。 处理具有层级结构的复杂数据。
错误处理 ValidationError 提供详细且可编程的错误报告。 向客户端返回结构化的错误信息。

备注:

  1. 拥抱类型注解:用类型注解定义清晰的接口,充分利用 IDE 的自动补全和检查功能。

  2. 模型与业务分离:将 Pydantic 模型看作系统的"边界"(入口和出口)数据定义,而非内部业务逻辑对象。

  3. 善用 model_dump() :在存储或传输数据时,应使用此方法显式导出数据,而不是直接访问 __dict__

更多用法可以参考中文官网介绍:https://pydantic.com.cn/

相关推荐
008爬虫实战录5 小时前
【码上爬】 题十:魔改算法 堆栈分析,找加密值过程详解
前端·python·算法
人道领域5 小时前
Java基础热门八股总结:八种基本数据类型 + 装箱拆箱 + 缓存机制,(90%的Java新手都搞不清的装箱拆箱问题)
java·开发语言·python
机汇五金_5 小时前
专业的电脑机箱厂商
python
smileNicky6 小时前
Spring框架懒加载怎么实现?
python·spring·rpc
熊猫_豆豆6 小时前
麦克斯韦方程组(电磁效应Python展示)
开发语言·python·电磁感应·麦克斯韦方程组
SilentSamsara6 小时前
属性查找顺序:实例 → 类 → 父类的完整 MRO
开发语言·python·算法·青少年编程
甄心爱学习7 小时前
【项目实训】法律文书智能摘要系统6
python·个人开发
小白学大数据7 小时前
Scrapling:极简高效的 Python 智能爬虫框架
开发语言·爬虫·python·数据分析
辣椒思密达7 小时前
Python爬虫中如何正确配置住宅IP代理?新手避坑指南
c语言·python