Python Pydantic数据验证的实现

 更新时间:2025年04月09日 09:54:18   作者:山河不见老  
本文主要介绍了Python Pydantic数据验证的实现

1. 什么是 Pydantic?

Pydantic 是一个功能强大的 Python 数据验证库,它通过 Python 类型注解实现快速的数据验证和转换。它不仅提供了全面的类型验证、自动数据转换和详细的错误处理机制,还具有基于 Rust 实现的高性能核心验证器。凭借其优秀的 IDE 支持和可扩展性,Pydantic 在 FastAPI 等 Web 框架、配置管理、数据序列化以及 API 接口模型定义等多个场景中得到广泛应用。

2. 安装

pip install pydantic
pip install pydantic-settings

3. 基础使用

在开始使用 Pydantic 之前,我们需要了解它的核心概念和基本用法。Pydantic 的核心是通过定义模型类来实现数据验证,这些模型类继承自 BaseModel。

3.1 创建基础模型

基础模型是 Pydantic 中最常用的功能。通过继承 BaseModel 类,我们可以定义数据结构和类型约束。每个字段都可以使用 Python 的类型注解来指定其类型,这些类型会在数据验证时被强制执行。

from pydantic import BaseModel
from typing import Optional
from datetime import datetime

class User(BaseModel):
    id: int
    username: str
    email: str
    full_name: Optional[str] = None  # 可选字段
    created_at: datetime = datetime.now()  # 默认值

# 创建实例
user = User(
    id=1,
    username="john_doe",
    email="john@example.com"
)

# 访问数据
print(user.username)  # 输出: john_doe

# 转换为字典
user_dict = user.model_dump()

字段定义说明:

  • id: int - 必填的整数字段
  • username: str - 必填的字符串字段
  • email: str - 必填的邮箱字段
  • full_name: Optional[str] - 可选的字符串字段,可以为 None
  • created_at: datetime - 带默认值的日期时间字段

3.2 数据验证

Pydantic 的数据验证是自动进行的,当创建模型实例时,输入数据会自动根据定义的类型进行验证和转换。如果验证失败,Pydantic 会抛出详细的 ValidationError 异常。

from pydantic import BaseModel, EmailStr, ValidationError

class UserRegistration(BaseModel):
    username: str
    email: EmailStr
    age: int

try:
    # 尝试创建无效数据
    user = UserRegistration(
        username="john",
        email="invalid-email",  # 无效邮箱
        age="not_a_number"  # 无效年龄
    )
except ValidationError as e:
    print("验证错误:")
    for error in e.errors():
        print(f"- {error['loc'][0]}: {error['msg']}")

当验证失败时,错误信息会包含:

  • 具体是哪个字段验证失败
  • 失败的原因
  • 期望的数据类型
  • 实际接收到的数据类型

3.3 嵌套模型

在实际应用中,数据结构往往是嵌套的。Pydantic 完全支持模型嵌套,这使得我们可以构建复杂的数据结构,同时保持数据验证的严谨性。

from typing import List

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

class User(BaseModel):
    name: str
    addresses: List[Address]

# 使用嵌套模型
user = User(
    name="John Doe",
    addresses=[
        {"street": "123 Main St", "city": "Boston", "country": "USA"},
        {"street": "456 Park Ave", "city": "New York", "country": "USA"}
    ]
)

嵌套模型的优势:

  • 保持数据结构的层次清晰
  • 支持复杂的数据验证逻辑
  • 方便数据的序列化和反序列化

4. 常用验证规则

Pydantic 提供了丰富的验证规则,可以满足各种复杂的数据验证需求。这些规则可以组合使用,构建出强大的验证逻辑。

4.1 基础验证规则

Field 类是 Pydantic 提供的字段定义工具,它允许我们为字段添加各种验证规则和元数据。通过 Field,我们可以定义字段的约束条件、默认值和描述信息。

from pydantic import BaseModel, Field, EmailStr, HttpUrl, constr

class User(BaseModel):
    # 字符串验证
    name: str = Field(..., min_length=2, max_length=50)  # 必填,长度2-50
    username: str = Field(..., pattern="^[a-zA-Z0-9_-]+$")  # 只允许字母、数字、下划线和横杠

    # 数值验证
    age: int = Field(..., ge=0, le=120)  # 大于等于0,小于等于120
    score: float = Field(..., gt=0, lt=100)  # 大于0,小于100

    # 特殊类型验证
    email: EmailStr  # 邮箱验证
    website: HttpUrl  # URL验证

    # 可选字段
    description: str | None = Field(None, max_length=1000)  # 可选,最大长度1000

验证规则说明:

  • min_length/max_length: 控制字符串长度
  • pattern: 使用正则表达式验证字符串格式
  • ge/le: 大于等于/小于等于
  • gt/lt: 大于/小于

4.2 列表验证

from typing import List

class Order(BaseModel):
    # 列表长度验证
    items: List[str] = Field(..., min_items=1, max_items=10)

    # 列表元素唯一性验证
    tags: List[str] = Field(..., unique_items=True)

    # 价格必须为正数的列表
    prices: List[float] = Field(..., gt=0)

4.3 自定义验证器

from pydantic import BaseModel, model_validator, field_validator
from datetime import datetime

class Order(BaseModel):
    order_id: str
    created_at: datetime
    total_amount: float
    items_count: int

    # 字段级验证器
    @field_validator('order_id')
    def validate_order_id(cls, v):
        if not v.startswith('ORD-'):
            return f'ORD-{v}'
        return v

    # 模型级验证器
    @model_validator(mode='after')
    def validate_total(self):
        if self.total_amount <= 0 and self.items_count > 0:
            raise ValueError('Total amount must be positive when items exist')
        return self

4.4 条件验证

from typing import Optional
from pydantic import BaseModel, Field, model_validator

class Product(BaseModel):
    name: str
    price: float
    discount: Optional[float] = None
    final_price: Optional[float] = None

    @model_validator(mode='after')
    def calculate_final_price(self):
        if self.discount is not None:
            if not 0 <= self.discount <= 1:
                raise ValueError('Discount must be between 0 and 1')
            self.final_price = self.price * (1 - self.discount)
        else:
            self.final_price = self.price
        return self

4.5 常用验证类型

from pydantic import BaseModel, Field, EmailStr, HttpUrl, conint, confloat, constr

class UserProfile(BaseModel):
    # 受约束的字符串
    username: constr(min_length=3, max_length=20, pattern="^[a-zA-Z0-9_]+$")

    # 受约束的整数
    age: conint(ge=0, le=120)

    # 受约束的浮点数
    height: confloat(ge=0, le=300)

    # 枚举选择
    status: str = Field(..., pattern="^(active|inactive|pending)$")

    # 布尔值
    is_active: bool = True

这些验证规则涵盖了日常开发中最常见的数据验证场景。通过组合使用这些规则,可以构建出复杂的数据验证逻辑。记住几个要点:

  • Field(…) 中的 … 表示该字段必填
  • 使用 Optional 或 | None 表示可选字段
  • 验证器分为字段级 (field_validator) 和模型级 (model_validator)
  • 可以组合多个验证规则
  • 验证规则的顺序: 先定义字段,再添加验证规则
  • 验证规则的执行顺序: 先定义的规则先执行

5. 实际应用示例

5.1 API 请求验证

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = False

@app.post("/items/")
async def create_item(item: Item):
    return item

5.2 配置管理

from pydantic_settings import BaseSettings, SettingsConfigDict

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

    model_config = SettingsConfigDict(env_file='.env')

# 从环境变量加载配置
settings = Settings()

6. 小技巧

6.1. 数据转换:

# 字典转模型
data = {"name": "John", "age": "25"}  # 注意 age 是字符串
user = User.model_validate(data)  # 推荐使用 model_validate 而不是 parse_obj

# 模型转 JSON
json_str = user.model_dump_json()  # 推荐使用 model_dump_json 而不是 json()

# 模型转字典
user_dict = user.model_dump()  # 推荐使用 model_dump 而不是 dict()

# 模型转 JSON 字符串(带缩进)
json_str = user.model_dump_json(indent=4)

# JSON 字符串转模型
user = User.model_validate_json(json_str)

6.2 错误处理:

try:
    user = User(name="John", age="invalid")
except ValidationError as e:
    print("数据无效:", e)

到此这篇关于Python Pydantic数据验证的实现的文章就介绍到这了,更多相关Python Pydantic数据验证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • 基于Python的socket库实现通信功能的示例代码

    基于Python的socket库实现通信功能的示例代码

    本文主要给大家介绍了如何使用python的socket库实现通信功能,这里简单的给每个客户端增加一个不重复的uid,客户端之间可以根据这个uid选择进行广播通信,感兴趣的小伙伴快来看看吧
    2023-08-08
  • pytest自动化测试fixture的作用域实例化顺序及可用性

    pytest自动化测试fixture的作用域实例化顺序及可用性

    这篇文章主要介绍了pytest自动化测试中fixture的作用域、实例化顺序及可用性的详解示例有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • python使用 __init__初始化操作简单示例

    python使用 __init__初始化操作简单示例

    这篇文章主要介绍了python使用 __init__初始化操作,结合实例形式分析了Python面向对象程序设计中使用__init__进行初始化操作相关技巧与注意事项,需要的朋友可以参考下
    2019-09-09
  • python实现批量打开windows cmd过程

    python实现批量打开windows cmd过程

    作者分享了使用Python批量打开cmd窗口并使用subprocess模块实现tcping测试的方法,为了解决手动关闭窗口耗时的问题,作者推荐使用kill进程名称的方式结束运行,提高测试效率
    2026-05-05
  • 在Python中使用第三方模块的教程

    在Python中使用第三方模块的教程

    这篇文章主要介绍了在Python中使用第三方模块的教程,是Python学习当中的基础知识,需要的朋友可以参考下
    2015-04-04
  • python使用psutil模块获取系统状态

    python使用psutil模块获取系统状态

    作为程序猿,大家可能都熟悉linux系统的基础信息获取方法都是通过shell来获取,但是在python中,我们还可以使用psutil模块来获取系统信息。psutil模块把shell查看系统基础信息的功能都包装了下,使用更加简单,功能丰富。
    2016-08-08
  • Python如何实现动态数组

    Python如何实现动态数组

    这篇文章主要介绍了Python如何实现动态数组,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • python 解压pkl文件的方法

    python 解压pkl文件的方法

    今天小编就为大家分享一篇python 解压pkl文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • Django框架使用mysql视图操作示例

    Django框架使用mysql视图操作示例

    这篇文章主要介绍了Django框架使用mysql视图操作,结合实例形式分析了mysql视图的创建、查看以及Django框架使用mysql视图相关操作技巧,需要的朋友可以参考下
    2019-05-05
  • python实现sm2和sm4国密(国家商用密码)算法的示例

    python实现sm2和sm4国密(国家商用密码)算法的示例

    这篇文章主要介绍了python实现sm2和sm4国密(国家商用密码)算法的示例,帮助大家使用python加密文件,感兴趣的朋友可以了解下
    2020-09-09

最新评论