pydantic详解【持续更新】

部署运行你感兴趣的模型镜像

pydantic

pydantic简介

Pydantic 是一个 Python 库,它使用 Python 3.6 及以上版本的类型提示功能来验证和管理数据。Pydantic 的主要目标是让数据验证变得简单而快速。它通过预定义的模型来验证数据的结构、类型、约束等,同时提供错误信息以帮助调试。Pydantic 通常用于数据解析、数据校验、配置管理、API请求与响应的序列化与反序列化等场景。

以下是 Pydantic 的一些核心特性:

  • 类型注解: Pydantic 使用 Python 的类型注解来定义数据模型的结构,提供了一种直观且简洁的方式来描述数据。

  • 数据校验: 它提供了多种内置的数据校验器,可以确保数据满足特定的格式和约束,例如字符串长度、数字大小、邮箱格式等。

  • 自动错误报告: 当数据不符合预期时,Pydantic 可以自动生成详细的错误报告,包括错误字段和具体的错误信息。

  • 类型转换: Pydantic 会尝试将输入的数据自动转换为定义的字段类型(如果可能的话),比如将字符串 “123” 转换为整数 123。

  • ORM 模式: Pydantic 支持 ORM 模式,可以与 ORM 框架(如 SQLAlchemy)一起使用,直接从数据库模型生成 Pydantic 模型。

  • JSON 支持: Pydantic 模型可以轻松地从 JSON 对象创建,也可以序列化为 JSON 对象,方便与 RESTful API 交互。

  • 可扩展: 可以通过自定义校验器和模型方法来扩展 Pydantic 的功能,以满足复杂的业务需求。

  • 编辑器集成: Pydantic 与现代 Python 编辑器(如 PyCharm)集成良好,可以提供自动补全和类型检查等功能。

Pydantic 库是 FastAPI 框架的一个重要组成部分,FastAPI 使用 Pydantic 来处理请求和响应数据的验证和序列化。

pydantic用法

基本用法

  • pydantic库的数据定义方式是通过BaseModel类来进行定义的,所有基于pydantic的数据类型本质上都是一个BaseModel类,它最基本的使用方式如下:
from pydantic import BaseModel

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

# 创建一个 User 模型实例
user = User(id=1, name='John Doe', age=30, email='johndoe@example.com')

# 访问模型数据
print(user.id)       # 输出: 1
print(user.email)    # 输出: johndoe@example.com

# 模型实例可以转换为字典或 JSON
print(user.dict())   # 输出模型的字典表示
print(user.json())   # 输出模型的 JSON 字符串表示
  • 在 Pydantic 中,当传入的字典或其他数据源包含模型未定义的字段时,默认情况下,这些额外的字段会被忽略,不会引发错误。这意味着 BaseModel 会自动过滤掉那些未在模型中声明的字段
from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    email: str

# 假设我们有一个包含额外字段 'age' 和 'location' 的字典
input_data = {
    'id': 1,
    'name': 'John Doe',
    'email': 'johndoe@example.com',
    'age': 30,
    'location': 'New York'
}

# 创建一个 User 实例,传入包含额外字段的字典
user = User(**input_data)

# 输出 user 对象的属性,只包含模型定义的字段
print(user.id)       # 输出: 1
print(user.name)     # 输出: John Doe
print(user.email)    # 输出: johndoe@example.com

# 额外的字段 'age' 和 'location' 不会被添加到 user 对象中
# 以下代码会抛出 AttributeError,因为 'age' 和 'location' 不是 User 模型的字段
# print(user.age)    # AttributeError
# print(user.location)  # AttributeError

# 通过 dict() 方法查看 user 对象的内部字典,也不会包含额外的字段
print(user.dict())   # 输出: {'id': 1, 'name': 'John Doe', 'email': 'johndoe@example.com'}
  • 如果你想要在模型中显式禁止额外的字段,可以设置 Config 类的 extra 属性为 forbid,(从 Pydantic 2.0 开始,使用 pydantic.config.Extra 的方式已经不再推荐,而是建议直接使用字符串字面量来指定 extra 的配置)如果尝试传入包含未定义字段的数据,将会引发 ValidationError。通过这种方式,你可以根据需要控制模型是否接受额外的字段。
from pydantic import BaseModel, Extra

class User(BaseModel):
    id: int
    name: str
    email: str
    
    class Config:
        extra = 'forbid'

input_data = {
    'id': 1,
    'name': 'John Doe',
    'email': 'johndoe@example.com',
    'age': 30,
    'location': 'New York'
}

# 这将抛出 ValidationError,因为 'age' 和 'location' 未在 User 模型中定义
user = User(**input_data)

pydantic基本数据类型

from pydantic import BaseModel
from typing import Dict, List, Sequence, Set, Tuple

class Demo(BaseModel):
    a: int # 整型
    b: float # 浮点型
    c: str # 字符串
    d: bool # 布尔型
    e: List[int] # 整型列表
    f: Dict[str, int] # 字典型,key为str,value为int
    g: Set[int] # 集合
    h: Tuple[str, int] # 元组

高级数据结构

enum数据类型

在 Python 中,enum 是一个用于创建枚举的模块。枚举(Enumerations)是一种组织具有命名值的数据类型的方式,每个值在枚举中都是唯一的。枚举类型可以使代码更清晰,更易于阅读和维护。要使用枚举类型,你需要导入 enum 模块,并且定义一个继承自 enum.Enum 的类。枚举成员由类属性表示,每个成员有两个关键特性:一个名称和一个值。

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

# 使用枚举成员
favorite_color = Color.RED
print(favorite_color)  # 输出: Color.RED
print(favorite_color.name)  # 输出: 'RED'
print(favorite_color.value)  # 输出: 1

# 枚举成员是唯一的
print(Color.RED is Color.GREEN)  # 输出: False

# 通过值或名称访问枚举成员
print(Color(1))  # 输出: Color.RED
print(Color['RED'])  # 输出: Color.RED
可选数据类型

如果一个数据类型不是必须的,可以允许用户在使用中不进行传入,则我们可以使用typing库中的Optional方法进行实现

from typing import Optional
from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: Optional[int]
数据默认值的设置

不传入参数,自动获取BaseModel中设置的默认值

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    gender: str = "man"

p = Person(name="Tom")
print(p.json()) # {"name": "Tom", "gender": "man"}
异名数据传递方法

假设我们之前已经定义了一个schema,将其中某一个参量命名为了A,但是在后续的定义中,我们希望这个量被命名为B

  • 通过Field方法来实现
from pydantic import BaseModel, Field

class Password(BaseModel):
    password: str = Field(alias = "key")
  • 在传入时,用key关键词来传入password变量,如果使用password作为关键字传入参数将会报错
p = Password(key="123456")
print(p.json()) # {"password": "123456"}
多级schema定义样例
from pydantic import BaseModel, EmailStr

# 定义一个 Address 模型,表示地址信息
class Address(BaseModel):
    street: str
    city: str
    zip_code: str
    country: str

# 定义一个 User 模型,包含基本用户信息和地址
class User(BaseModel):
    id: int
    name: str
    email: EmailStr
    address: Address  # 使用 Address 类型作为 User 的一个字段

# 定义一个 Company 模型,包含公司信息和员工列表(每个员工是一个 User 实例)
class Company(BaseModel):
    name: str
    address: Address
    employees: list[User]  # User 列表作为 Company 的一个字段

# 创建 Address 实例
address = Address(
    street="123 Main St",
    city="Anytown",
    zip_code="12345",
    country="USA"
)

# 创建 User 实例
user = User(
    id=1,
    name="John Doe",
    email="johndoe@example.com",
    address=address
)

# 创建 Company 实例,包含一个员工
company = Company(
    name="Example Corp",
    address=address,
    employees=[user]  # 将 User 实例放入列表中
)

print(company.model_dump_json(indent=4)) 

>>> output
{
    "name": "Example Corp",
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "zip_code": "12345",
        "country": "USA"
    },
    "employees": [
        {
            "id": 1,
            "name": "John Doe",
            "email": "johndoe@example.com",
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "zip_code": "12345",
                "country": "USA"
            }
        }
    ]
}
  • 这里用到了pydantic中的model_dump_json方法,可以将json格式依照自己的要求输出,indent=4表示按照数据结构,缩进四格

数据检查方法考察

pydantic本身提供了上述基本类型的数据检查方法,但是,除此之外,我们也可以使用validator和config方法来实现更为复杂的数据类型定义以及检查

validator用法考察

在 Pydantic 中,validator 是一个装饰器,用于在模型实例化之前对字段值进行额外的校验或处理。validator 装饰器允许你定义自定义校验函数,确保数据满足特定的条件。这些自定义函数可以对一个或多个字段进行校验,并且可以在函数中抛出 ValueError 或 TypeError 来表示校验失败。

from pydantic import BaseModel, ValidationError, validator

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

    # 使用 validator 装饰器定义一个校验函数
    @validator('age')
    def check_age(cls, value):
        if value < 0:
            raise ValueError('Age must be a positive integer')
        if value > 150:
            raise ValueError('Age must be less than or equal to 150')
        return value

# 正确的用法,创建一个 User 实例,年龄在合理范围内
user = User(name='Alice', age=30)
print(user)

# 错误的用法,试图创建一个年龄为负数的 User 实例,将引发 ValidationError
try:
    user = User(name='Bob', age=-5)
except ValidationError as e:
    print(e)

# 错误的用法,试图创建一个年龄超过 150 的 User 实例,将引发 ValidationError
try:
    user = User(name='Charlie', age=200)
except ValidationError as e:
    print(e)
Config方法考察

如果要对BaseModel中的某一基本型进行统一的格式要求,我们还可以使用Config方法来实现

from pydantic import BaseModel

class Password(BaseModel):
    password: str
        
    class Config:
        str_min_length = 6 # 令Password类中所有的字符串长度均要不少于6
        str_max_length = 20 # 令Password类中所有的字符串长度均要不大于20

password = Password(password="123456"*100)

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值