Python学习之-Pydantic详解

前言:

Pydantic 是一个 Python 库,用于数据解析和验证。它主要基于 Python 类型提示来实现数据的校验和设定限制条件。在 Pydantic 中,BaseModel 是一个核心基类,用于创建数据模型。

1 BaseModel的主要作用包括:

数据验证(Validation):
BaseModel 类提供了自动数据验证的功能。当你创建一个基于 BaseModel 的子类并且为其字段添加类型注解(type annotations),Pydantic 会在实例化对象时自动校验给定的数据是否符合预期类型和约束。
数据转换(Conversion):
Pydantic 会尝试将输入数据转换成声明的数据类型。例如,如果一个字段被声明为 int 类型,但输入数据是一个数字字符串,如 “123”,Pydantic 会尝试转换这个字符串为整型 123。
模型实例化:
BaseModel 中提供的构造器可以让你轻松地实例化模型,并为其填充数据。在实例化过程中,数据会自动经过验证和转换。
错误处理:
如果数据不符合预期,Pydantic 会抛出描述性的错误(通常是 ValidationError 异常),告诉你哪些数据是无效的以及具体原因。
字段别名:
BaseModel 允许你为模型的字段设定别名,这样在解析外部数据如 JSON 时,如果其字段名称与你的模型字段不一致,依然可以正确匹配和解析。
JSON序列化与反序列化:
BaseModel 提供了 .json() 和 .parse_raw() 两个方法用于模型对象的 JSON 序列化(将 Python 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串或二进制数据解析成 Python 对象)。
示例(Schema)生成:
BaseModel 可以自动为你的模型生成 JSON Schema,这在构建 RESTful API 并使用 OpenAPI/Swagger 进行文档化时非常有用。
ORM 模式:
Pydantic 具有一个 ORM 模式,允许 BaseModel 与 ORMs(如 SQLAlchemy)配合使用,可直接从 ORM 对象创建 Pydantic 模型实例。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""
from datetime import datetime
from typing import Optional, List

from pydantic import BaseModel


# 定义模型
class User(BaseModel):
    id: int
    name: str = "Jane Doe"  # 提供默认值
    signup_ts: Optional[datetime] = None
    friends: List[int] = []


# 实例化模型,自动进行数据验证
user = User(id=123, signup_ts="2021-01-01 12:22", friends=[1, 2, 3])

# 这里friends为int类型的时候运行会报如下错误
'''
pydantic_core._pydantic_core.ValidationError: 1 validation error for User
friends
  Input should be a valid list [type=list_type, input_value=1, input_type=int]

'''
# user = User(id=123, signup_ts="2021-01-01 12:22", friends=1)

# 你也可以序列化模型
user_json = user.json()

# 或对初始 JSON 数据进行解析创建模型
original_data = '{"id": "123", "signup_ts": "2021-01-01 12:22", "friends": [1, 2, 3]}'
user = User.parse_raw(original_data)

2 Field

在 Pydantic 中,Field 函数用于提供更多的配置和校验选项给 BaseModel 的字段。通过使用 Field,你可以为模型的字段指定默认值、验证规则、字段描述、别名等。
以下是 Field 的一些常用用法:
设置字段别名:
当你想要接受的 JSON 字段名与 Python 的变量命名规范不一致时,可以使用 Field 的 alias 参数。
字段校验:
除了基本的类型校验之外,Field 还可以提供额外的校验选项,比如字符串长度、数字的大小范围、使用正则表达式等。
描述和元数据:
给字段提供描述信息,这些信息可以用于生成文档或者提供模型字段的元数据。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""

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


class Item(BaseModel):
    name: str = Field(..., title="The name of the item", max_length=300)
    description: Optional[str] = Field(None, title="The description of the item", max_length=500)
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    tax: Optional[float] = None
    tags: List[str] = []


# 使用别名
class User(BaseModel):
    username: str = Field(..., alias="user_name")


item = Item(name='Some Item', price='50.2')
print(item.json())  # 输出 {"name":"SomeItem","description":null,"price":50.2,"tax":null,"tags":[]}

# 如果是price未定义的话会返回 
# item = Item(name='Some Item')
# pydantic_core._pydantic_core.ValidationError: 1 validation error for Item
# price
#   Field required [type=missing, input_value={'name': 'Some Item'}, input_type=dict]

# 实例化模型时,需要使用别名字段
user_data = '{"user_name": "johndoe"}'
user = User.parse_raw(user_data)
print(user.username)  # 输出: johndoe

在上述 Item 类中,每个字段都使用了 Field 函数来定义额外的信息和校验规则。name 字段是必须的 (… 为 Pydantic 的特殊语法标记,表明字段是必需的),并且其最大长度为300个字符。price 字段也是必须的,并且它的值必须大于0。

在 User 类示例中,通过 alias 参数将 username 字段映射到 JSON 中的 user_name 字段,从而在解析时可以正确地从 JSON 字段中获取数据。

注意,Pydantic 模型的实例化(例如上面的 user = User.parse_raw(user_data))在提供数据时将根据实际情况使用别名。如果你直接通过关键字参数创建实例,比如 User(username=“johndoe”),那么应当使用你在模型定义中的字段名而不是别名。在进行 JSON 序列化和反序列化时,别名将被使用。

Field 是 Pydantic 提供的一种非常灵活的方式,用于定义额外的数据描述和校验逻辑,并且非常适用于复杂场景和API文档自动生成。

2.1 解析原始数据:

如果你有一些原始数据,比如 JSON 字符串,你可以使用 parse_raw() 或 parse_obj() 方法将其解析成 Item 实例。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""
import json
from pydantic import BaseModel, Field, ValidationError
from typing import List, Optional


class Item(BaseModel):
    name: str = Field(..., title="The name of the item", max_length=300)
    description: Optional[str] = Field(None, title="The description of the item", max_length=500)
    price: float = Field(..., gt=0, description="The price must be greater than zero")
    tax: Optional[float] = None
    tags: List[str] = []


if __name__ == '__main__':

    # 假设我们有这样一个 JSON 字符串
    json_data = '{"name": "Special Item", "price": 99.99, "tags": ["limited", "new"]}'

    try:
        # 使用 parse_raw 方法从 JSON 字符串创建一个 Item 实例
        item = Item.parse_raw(json_data)

        # 使用这个实例
        print(item.name)  # 输出: Special Item
        print(item.price)  # 输出: 99.99
        print(item.tags)  # 输出: ['limited', 'new']
    except ValidationError as e:
        print("数据验证失败:", e.json())

在上例中,我们创建一个 JSON 字符串 json_data,然后使用 Item.parse_raw() 方法将其转换为 Item 类实例。如果传递的数据无效或无法转换为正确的类型,Pydantic 会引发 ValidationError。

3 内建的校验器

Pydantic 提供了内建的校验器(如 EmailStr、HttpUrl、conint 等),可以应用于模型字段中,简化了常见数据格式的校验的举例说明

3.1 EmailStr:用于验证电子邮件地址格式。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""
from pydantic import BaseModel, EmailStr, ValidationError


class User(BaseModel):
    name: str
    email: EmailStr


# 正确的电子邮件格式
user = User(name='Alice', email='alice@example.com')

# 错误的电子邮件格式将抛出 ValidationError
try:
    user = User(name='Bob', email='bob.com')
except ValidationError as e:
    print(e)

3.2 HttpUrl:用于验证 HTTP URL 格式。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""
from pydantic import BaseModel, HttpUrl, ValidationError


class Website(BaseModel):
    url: HttpUrl


# 正确的 URL 格式
website = Website(url='http://www.example.com')

# 错误的 URL 格式将抛出 ValidationError
try:
    website = Website(url='not-a-url')
except ValidationError as e:
    print(e)

# 1 validation error for Website
# url
#   Input should be a valid URL, relative URL without a base [type=url_parsing, input_value='not-a-url', input_type=str]

3.3 conint:是一个约束型整数,允许设置最大值、最小值等约束条件。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/4/8 6:25
# @Author  : Summer
# @File    : test.py
# @describe:
"""
from pydantic import BaseModel, conint, ValidationError


class Player(BaseModel):
    age: conint(gt=0, lt=100)  # age 必须大于 0 且小于 100


# 正确的年龄范围
player = Player(age=25)

# 错误的年龄范围将抛出 ValidationError
try:
    player = Player(age=-1)
except ValidationError as e:
    print(e)

# 1 validation error for Player
# age
#   Input should be greater than 0 [type=greater_than, input_value=-1, input_type=int]

这些内建校验器是基于更通用的校验器,如 ConstrainedStr 和 ConstrainedInt 的特化,它们提供简便的方式来验证和转换数据,同时避免编写重复的校验逻辑。
Pydantic 还提供了其他校验器,如 PositiveInt(正整数)、NegativeFloat(负浮点数)、conlist(具有特定长度的列表)等。这里就不在这里细说了,有兴趣的可以尝试写代码了解,这些使得定义与各种数据类型和条件约束兼容的模型变得非常容易。当数据输入不符合预期时,Pydantic 会抛出 ValidationError,并提供详细的错误信息指出具体的问题字段和问题所在。

Pydantic总结

Pydantic 的主要优势在于其结合了灵活性和强大的数据处理能力,同时简化了常规的数据校验任务,让开发人员更专注于业务逻辑的实现。它通常用于快速开发中,特别是在构建API、数据交互和设置管理场景中发挥重要作用。
数据校验:
Pydantic 使用模型类(BaseModel 的子类)来定义数据的形状,包括数据类型和可能的额外约束。这些模型用于自动校验传入数据是否符合预期的格式,保证数据的有效性和准确性。

类型转换:
Pydantic 尝试将输入数据转换成声明的数据类型。例如,如果一个模型字段声明为 int 而提供的数据是字符串 “123”,Pydantic 将尝试转换字符串为整数。如果转换成功,则保存这个整数值;如果失败,则抛出一个错误。

数据序列化与反序列化:
Pydantic 模型可以序列化为 JSON 或其他格式的字符串,也可以从 JSON 或字典中反序列化回 Python 对象,使得在不同系统或网络之间传递和处理结构化数据变得简单。

编辑环境和设置管理:
Pydantic 可用于管理应用程序的配置和环境设置。通过创建设置模型,可以轻松读取环境变量并将其转换为合适的数据类型。

生成 JSON Schema:
Pydantic 可以从模型自动生成 JSON Schema,这在创建API文档或使用合适的工具进行前后端交互时非常有用。

模型继承和泛型:
Pydantic 支持模型继承和泛型模型,允许模型之间共享属性和行为,从而避免重复代码,并支持更复杂的数据结构。

开箱即用的校验器:
Pydantic 提供了内建的校验器(如 EmailStr、HttpUrl、conint 等),可以应用于模型字段中,简化了常见数据格式的校验。

自定义校验逻辑:
可以定义自己的校验函数,以校验复杂的数据逻辑,或在数据加载到模型之前/之后执行特定的操作。

优雅的错误处理:
当数据校验失败时,Pydantic 会提供详细的错误报告,直接说明哪个字段出了问题以及问题的性质,便于调试和用户反馈。

  • 32
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Pydantic是一个Python库,用于数据验证和解析。它提供了一种简单且强大的方式来定义数据模型,并且可以验证输入数据的有效性。通过使用Pydantic,您可以轻松地定义和处理复杂的数据结构。 安装Pydantic的扩展功能可以通过pip命令来完成,例如安装邮件验证支持可以使用以下命令:pip install pydantic[email]。同样地,您也可以安装dotenv文件支持或同时安装多个扩展功能。 Pydantic的核心类是BaseSettings类,它允许在验证请求数据和加载系统设置的上下文中使用。在验证请求数据的上下文中,您可以使用基本数据类型进行验证。而在加载系统设置的上下文中,您可以从环境变量中读取设置,并且还可以处理更复杂的对象,例如DSN和Python对象。 一个很大的优势是,Pydantic的模型的定义与Python的类型提示密切相关。如果您熟悉使用Python类型提示,那么您就知道如何使用Pydantic。数据结构只是使用类型注释定义的类的实例,因此自动完成、linting、mypy、IDE(尤其是PyCharm)和您的直觉都应该与您的验证数据正常工作。您无需学习新的模式定义微语言,只需使用Python类型提示即可定义数据模型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [pythonpydantic库](https://blog.csdn.net/qq_62789540/article/details/127069443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏天Aileft

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值