Python库Pydantic简介:
Pydantic 是一个用于 Python 的数据验证库,特别适用于构建 RESTful API 服务,尤其是结合 FastAPI 和 Starlette 框架时。它利用 Python 的类型注解系统,可以高效且准确地验证和清理传入应用程序的数据。Pydantic 提供了强类型模式验证,能够确保数据结构一致性和安全性。
常用功能与代码示例:
数据模型定义(Data Model Definition)
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
username: str
email: str
password_hash: str
is_active: bool = True
# 创建数据模型实例
user_data = {'id': 1, 'username': 'alice', 'email': '[email protected]', 'password_hash': 'hashed_password'}
user = User(**user_data)
# 验证数据,如果不合法则抛出ValidationError
try:
user = User(username='invalid type', email=12345) # email 应为字符串,会抛出错误
except ValidationError as e:
print(e)
数据验证(Data Validation)
Field
参数进一步定制验证规则,如长度限制、正则匹配等。from pydantic import BaseModel, Field
# 定义一个简单的用户模型
class User(BaseModel):
username: str = Field(..., min_length=4, max_length=20, title="用户名")
email: str = Field(..., regex=r'^[\w.-]+@[\w-]+\.\w{2,}$', title="邮箱地址")
age: int = Field(gt=0, lt=150, description="年龄(0-150岁)")
is_active: bool = Field(default=True, title="是否活跃")
# 示例用法
new_user_data = {
'username': 'shortname', # 不满足最小长度要求
'email': 'invalid_email', # 不符合邮箱格式
'age': 200, # 超过年龄范围
}
try:
user = User(**new_user_data)
except ValueError as e:
print(e.json()) # 输出验证错误信息
# 如果所有数据都有效,则正确创建 User 实例
valid_user_data = {
'username': 'validusername',
'email': '[email protected]',
'age': 30,
}
user = User(**valid_user_data)
在这个例子中:
username
字段被设置了最小长度为 4 个字符,最大长度为 20 个字符。email
字段通过正则表达式进行验证,确保其符合基本的电子邮件格式。age
字段要求大于 0 并且小于 150。is_active
字段默认值设为 True
。当尝试用不符合规则的数据创建 User
实例时,会抛出 ValidationError
异常,包含有关违反了哪些验证规则的信息。如果提供的数据满足所有字段的验证条件,则可以成功创建 User
实例。
3. 数据解析(Data Parsing)
from pydantic import BaseModel, Field
class Product(BaseModel):
id: int
name: str = Field(min_length=3, max_length=50)
price: float = Field(gt=0.0)
product_data = {'id': 1, 'name': 'Example Product', 'price': 9.99}
parsed_product = Product.parse_obj(product_data)
模型嵌套(Nested Models)
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
id: int
username: str
address: Address
user_data = {
'id': 1,
'username': 'johndoe',
'address': {'street': '123 Main St', 'city': 'Anytown', 'country': 'USA'}
}
user = User.parse_obj(user_data)
自定义验证函数(Custom Validators)
from pydantic import BaseModel, validator
class User(BaseModel):
first_name: str
last_name: str
@validator('first_name')
def validate_first_name(cls, v):
if len(v) < 2:
raise ValueError("First name must be at least two characters long")
return v.title()
user_data = {'first_name': 'a', 'last_name': 'Smith'}
try:
user = User(**user_data) # 会抛出验证错误,因为first_name太短
except ValueError as e:
print(e)
不太常用但仍然有用的功能:
Configurations(配置)
Config
类内嵌类来设定模型的行为,如是否导出未使用的字段、是否转换为驼峰式命名等。Schema Generation(模式生成)
schema()
方法生成 OpenAPI 或 JSON Schema,方便生成文档。Extra Fields Handling(额外字段处理)
Config.extra
设置决定是否允许模型接受额外的字段。Validation Error Handling(验证错误处理)
Async Support(异步支持)
Data Conversion(数据转换)
constr
、conint
、confloat
等预定义类型转换器进行数据类型转换。上述“不太常用”的功能并不是说它们不重要或不实用,而是相对于基础的数据验证和模型定义而言,在日常使用中可能频率稍低。根据具体应用场景,这些功能同样十分重要。
在 Pydantic 库中,BaseModel
是所有数据模型的基础类,而 Field
用于在模型类中定义和定制字段属性。下面分别介绍这两个概念的使用方法和示例。
BaseModel
的使用BaseModel
类提供了数据验证、序列化和反序列化的能力。当你定义一个继承自 BaseModel
的类时,实际上是在创建一个数据模型,其中包含了一系列具有特定类型和约束条件的字段。
from pydantic import BaseModel
class User(BaseModel):
id: int
username: str
email: str
is_active: bool = True
在上面的例子中,我们定义了一个 User
数据模型,其中包含四个字段:
id
: 必须为整数类型。username
: 必须为字符串类型。email
: 同样也是字符串类型。is_active
: 默认为布尔类型,且默认值为 True
。当我们使用这个模型时,可以通过构造函数传入相应的数据,Pydantic 将自动验证数据的类型和默认值。
valid_user_data = {'id': 1, 'username': 'Alice', 'email': '[email protected]'}
user = User(**valid_user_data)
Field
的使用Field
函数用来在定义模型字段时添加更多元化的验证和配置选项。它可以放在类型后面,用来设置字段的一些特性,比如默认值、最大长度、最小长度、范围限制等。
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str
description: str = Field(title="Item Description", max_length=100)
price: float = Field(gt=0, description="Price in USD")
# 使用 alias 进行字段重命名
json_data: dict = Field(..., alias="jsonData")
在这个 Item
模型中:
description
字段使用了 Field
添加了 title
属性,用于生成文档时显示的友好名称,并限制了最大长度为100个字符。price
字段设置了 gt=0
,意味着价格必须大于0。json_data
字段使用了 alias
参数,这意味着虽然在类内部我们使用的是 json_data
,但在外部输入或输出时,应当使用 jsonData
这个键。实例化时:
item_data = {'name': 'Widget', 'description': 'A fancy widget', 'jsonData': {'color': 'red'}, 'price': 9.99}
item = Item(**item_data)
通过以上示例可以看出,BaseModel
负责创建数据模型的骨架,并结合 Field
对各个字段进行详细的验证和配置。这样可以确保进入应用程序的数据始终满足预期的结构和规范。