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': 'alice@example.com', '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)
- Pydantic 在创建模型实例时会自动验证数据类型和约束条件。
- 可以通过
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': 'example@example.com',
'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(异步支持)
- Pydantic 支持异步验证和解析,尤其在 FastAPI 等异步框架中十分实用。
-
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': 'alice@example.com'}
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
对各个字段进行详细的验证和配置。这样可以确保进入应用程序的数据始终满足预期的结构和规范。