明天你会感谢今天奋力拼搏的你。
ヾ(o◕∀◕)ノヾ
Pydantic 是一个用于数据验证和设置管理的Python库,它使用类注解来定义数据模型。通过 Pydantic,可以轻松地创建、验证和操作复杂的数据结构,同时提供清晰的错误信息。
官方文档:https://docs.pydantic.dev/latest/api/base_model/
为什么使用Pydantic?
在Python中,类型提示是可选的,这意味着开发者可以声明变量的类型,但Python解释器不会强制执行这些类型。这在开发过程中可能会导致一些难以追踪的错误。Pydantic通过强制类型检查来解决这个问题,它提供了一种更加严格的方式来处理数据验证。
安装Pydantic:
官方文档:https://docs.pydantic.dev/latest/install/
pip install pydantic
# with the `email` extra:
pip install 'pydantic[email]'
# or with `email` and `timezone` extras:
pip install 'pydantic[email,timezone]'
扩展类型安装:https://docs.pydantic.dev/latest/migration/#color-and-payment-card-numbers-moved-to-pydantic-extra-types
pip install pydantic_extra_types
Pydantic 的核心原理是基于 Python 类型注解 和 数据验证:
定义一个继承自 BaseModel 的类来创建数据模型。这个类中的每个属性(字段)都代表模型的一部分,并且可以指定其类型和默认值。
如下示例,创建一个用户模型:
class User(BaseModel):
id: int #必须是整数
name: str = "CYX" # 字符串类型,默认值为 "CYX"。
signup_ts: datetime = None # 可选的时间戳,默认值为 None。
通过实例化模型类来验证传入的数据是否符合预期格式。如果数据不符合要求,Pydantic 会抛出详细的错误信息。
继续以上面的用户模型示例:
user_data = {
"id": 123,
"name": "Alice",
"signup_ts": "2023-10-01T12:00:00"
}
try:
user = User(**user_data)
print(user)
except ValueError as e:
print(e)
在这个例子中,user_data 是一个字典,包含了要验证的数据。通过 User(**user_data) 实例化 User 模型时,Pydantic 会自动验证这些数据是否符合模型定义的要求。
当数据验证失败时,Pydantic会抛出ValidationError。你可以通过try except捕获这个异常。
TIP:** 是 Python 中的字典解包操作符。在 Python 中,当你有一个字典,并且你想将其键值对作为关键字参数传递给一个函数或类构造函数时,可以使用 ** 操作符。这使得你可以避免手动将每个键值对传递给构造函数。
Field 函数可以为字段提供更多的配置选项,如默认值、别名、描述等。
示例:使用 Field 添加约束
class User(BaseModel):
id: int = Field(..., description="用户ID", gt=0) # ID 必须大于0
name: str = Field("John Doe", title="用户名", max_length=50) # 名称最大长度为50
signup_ts: datetime = Field(None, alias="signupTimestamp") # 别名为 signupTimestamp,默认值为 None
TIP:... 是 Python 的省略符(Ellipsis),表示“此处没有默认值”。在这里表示该字段是必填项,必须提供有效的值。如果你不提供这个字段的值,Pydantic 会抛出验证错误。
你可以为模型字段添加自定义验证逻辑,确保数据不仅符合类型要求,还满足特定的业务规则。
实现方式:通过在方法上添加@field_validator实现自定义的验证器
如下依然以用户模型为例,添加自定义验证器:
from pydantic.functional_validators import field_validator
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
age: int
@field_validator('age')
def check_age(cls, v):
if v < 0:
raise ValueError('年龄不能为负数')
return v
在这个例子中,check_age 方法是一个自定义验证器,它会在 age 字段被设置时自动调用,确保年龄不为负数。
更多验证方式,可以查看官方文档:https://docs.pydantic.dev/latest/concepts/validators/
Pydantic 支持 Python 内置的复杂类型,如列表、字典、集合等,并且可以嵌套使用。你还可以为这些复杂类型添加约束条件。
示例代码,演示列表和字典:
from typing import List,Dict
from pydantic import BaseModel
class User(BaseModel):
id: int
hobbies: List[str] # 必须是字符串列表
metadata: Dict[str, str] # 键和值都必须是字符串
user_data = {
"id": 123,
"hobbies": ["reading", "coding", "traveling"],
"metadata": {"role": "admin", "status": "active"}
}
user = User(**user_data)
print(user)
Pydantic 也支持与 Python 的 Enum 类结合使用,以确保字段值在预定义的范围内。
from enum import Enum
from pydantic import BaseModel
class Role(str, Enum):
ADMIN = "admin"
USER = "user"
class User(BaseModel):
id: int
role: Role
user_data = {
"id": 123,
"role": "admin"
}
user = User(**user_data)
print(user)
Pydantic 允许你定义自己的数据类型,以便更好地满足特定需求。你可以通过继承 BaseModel 或者使用 con* 系列函数来创建自定义类型。
可以通过继承 BaseModel 来创建自定义类,并为其添加验证逻辑。
自定义类也能正常嵌套到其他数据模型中,示例如下:
from pydantic import BaseModel
from pydantic.functional_validators import field_validator
from typing import List
class CustomType(BaseModel):
items: List[int]
@field_validator('items')
def check_items(cls, items):
for v in items:
if v < 0:
raise ValueError('所有项必须是非负数')
return v
class User(BaseModel):
id: int
custom_field: CustomType
user_data = {
"id": 123,
"custom_field": {"items": [1, 2, 3]}
}
user = User(**user_data)
print(user)
Pydantic 提供了一系列 con* 函数(如 constr, conint, confloat 等),用于创建带约束的自定义类型。
示例:定义带约束的字符串字段
from pydantic import BaseModel, constr
# 定义一个最小长度为3,最大长度为50的字符串类型
Username = constr(min_length=3, max_length=50)
class User(BaseModel):
id: int
username: Username
user_data = {
"id": 123,
"username": "alice"
}
user = User(**user_data)
print(user)
Pydantic 还支持使用正则表达式来验证字符串格式。
示例:使用正则表达式验证邮箱地址
from pydantic import BaseModel, constr
EmailStr = constr(pattern=r"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+")
class User(BaseModel):
id: int
email: EmailStr
user_data = {
"id": 123,
"email": "alice@example.com"
}
user = User(**user_data)
print(user)
Pydantic 提供了许多内置的实用类型,这些类型不仅简化了数据验证的过程,还提供了清晰的错误信息。
示例如下:
from pydantic import BaseModel, EmailStr, HttpUrl, FilePath, Json
class User(BaseModel):
email: EmailStr
website: HttpUrl
config_file: FilePath
settings: Json
user_data = {
"email": "alice@example.com",
"website": "https://example.com",
"config_file": "/path/to/config.json",
"settings": '{"theme": "dark", "notifications": true}'
}
user = User(**user_data)
print(user)
示例代码如下:
from pydantic import BaseModel, conint, confloat, PositiveInt, NegativeFloat
class Data(BaseModel):
age: conint(gt=0, le=120) # 年龄必须大于0且小于等于120
score: confloat(ge=0, le=100) # 分数必须在0到100之间
positive_age: PositiveInt # 正整数
negative_score: NegativeFloat # 负浮点数
data = {
"age": 30,
"score": 85.5,
"positive_age": 42,
"negative_score": -10.5
}
validated_data = Data(**data)
print(validated_data)
示例代码:
from pydantic import BaseModel, PastDate, FutureDate
from datetime import date, datetime
class Event(BaseModel):
start_date: PastDate # 必须是过去的日期
end_date: FutureDate # 必须是未来的日期
event_data = {
"start_date": date(2022, 1, 1),
"end_date": date(2024, 12, 31)
}
event = Event(**event_data)
print(event)
示例代码:
from pydantic import BaseModel, UUID4
from pydantic_extra_types.color import Color
from pydantic_extra_types.payment import PaymentCardNumber
class Product(BaseModel):
id: UUID4
card_number: PaymentCardNumber
color: Color
product_data = {
"id": "550e8400-e29b-41d4-a716-446655440000",
"card_number": "4242424242424242",
"color": "red"
}
product = Product(**product_data)
print(product)
全部评论