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)
31万+

被折叠的 条评论
为什么被折叠?



