# pydantic-数据模型定义与验证
# 概述
Pydantic是一个Python库,可以用于数据验证和数据转换。它提供了一个数据模型声明的方式,可以用来定义数据模型,然后可以使用这些数据模型来验证输入数据的类型和格式,并转换成Python对象。Pydantic还支持自动文档生成和API交互,是一个非常实用的工具。
数据模型声明可以通过定义Python类来实现,其中每个属性都可以指定类型、默认值、描述等属性。当创建类实例时,如果提供的数据与模型不匹配,则会抛出异常,这可以用来快速捕捉输入数据中的错误。Pydantic还提供了很多内置的验证器,比如长度、范围和正则表达式等。
另外,Pydantic还支持自动转换数据类型,可以将JSON、yaml等格式的数据转换成Python对象,也可以将Python对象转换成其他数据格式,比如JSON、msgpack等。
总之,Pydantic是一个非常实用的Python库,可以在许多场景中提高开发效率,比如Web开发、数据处理等。
# pydantic高级特性
# 1. 支持类型转换
Pydantic可以自动进行类型转换,比如将字符串转换成数字或日期。只需要在模型中指定合适的类型即可,Pydantic会自动将传入的数据转换成相应的类型。例如:
from datetime import date
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
birthdate: date
user_data = {'id': 1, 'name': 'John', 'birthdate': '2003-09-11'}
user = User(**user_data)
# 等价于
user = User(id=1, name='John', birthdate=date(2003, 9, 11))
# 2. 支持嵌套模型
Pydantic支持嵌套的模型定义,可以用来描述复杂对象,具有很高的灵活性。例如:
from pydantic import BaseModel
from typing import List
class Item(BaseModel):
id: int
name: str
price: float
class Order(BaseModel):
id: int
items: List[Item]
total: float
order_data = {'id': 1, 'items': [{'id': 1, 'name': 'apple', 'price': 2.0},
{'id': 2, 'name': 'banana', 'price': 1.5}],
'total': 3.5}
order = Order(**order_data)
# 等价于
order = Order(id=1, items=[Item(id=1, name='apple', price=2.0),
Item(id=2, name='banana', price=1.5)],
total=3.5)
# 3. 支持运算符重载
Pydantic支持运算符重载,可以将Pydantic对象视为普通对象来进行操作。例如:
from pydantic import BaseModel
class Point(BaseModel):
x: float
y: float
def __add__(self, other):
return Point(x=self.x+other.x, y=self.y+other.y)
p1 = Point(x=1, y=2)
p2 = Point(x=3, y=4)
p3 = p1 + p2
# p3 = Point(x=4.0, y=6.0)
# 4. 支持参数注释
Pydantic支持在模型中添加参数注释,可以用于自动生成API文档或其他文档。例如:
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = 'anonymous' # 用户名,默认为'anonymous'。
age: int = None # 年龄,默认为None。
# 使用示例
from pydantic import BaseModel, validator
from typing import Optional, List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
id: int
username: str
password: Optional[str] = None
@validator('id')
def id_must_be_positive(cls, v):
"""
自定义数据校验逻辑:ID必须为正整数
"""
if v <= 0:
raise ValueError('ID must be a positive integer')
return v
@app.post("/add_user")
async def add_user(user_data: List[User]):
# 验证输入数据是否符合模型定义
for user in user_data:
if not isinstance(user.id, int):
return {"success": False, "message": "ID must be an integer."}
if not isinstance(user.username, str):
return {"success": False, "message": "Username must be a string."}
if not isinstance(user.password, str):
return {"success": False, "message": "Password must be a string."}
# 将输入数据转换成Pydantic对象
users = [User(**user_dict) for user_dict in user_data]
# 处理业务逻辑
# ...
return {"success": True, "message": "User added successfully."}
在上面的示例中,我们给password字段添加了一个默认值None,意味着在创建User实例时,如果不显式指定password,则该字段的值将会是None。
我们还在id字段上定义了自定义验证器id_must_be_positive,用于检查ID是否为正整数。该验证器使用了validator装饰器,传入参数是需要进行验证的字段的名称id。验证函数的参数有两个,一个是被验证的类,另一个是被验证的值v。函数可以抛出异常来报告校验失败,或者返回值将会被认为是校验后新的值。
最后,我们需要注意到username字段并没有添加任何校验规则,也没有设置默认值。这意味着在创建User对象时,如果缺少username字段,将会抛出ValidationError异常。如果你想要username字段不是必需的,可以使用Optional类型装饰器,如上所示。
综上所述,Pydantic提供了灵活而强大的数据验证机制,通过使用自定义验证函数和装饰器,我们可以针对需要的字段和情景很方便地定义校验规则。