Python Pydantic數(shù)據(jù)驗證的實現(xiàn)
1. 什么是 Pydantic?
Pydantic 是一個功能強大的 Python 數(shù)據(jù)驗證庫,它通過 Python 類型注解實現(xiàn)快速的數(shù)據(jù)驗證和轉(zhuǎn)換。它不僅提供了全面的類型驗證、自動數(shù)據(jù)轉(zhuǎn)換和詳細的錯誤處理機制,還具有基于 Rust 實現(xiàn)的高性能核心驗證器。憑借其優(yōu)秀的 IDE 支持和可擴展性,Pydantic 在 FastAPI 等 Web 框架、配置管理、數(shù)據(jù)序列化以及 API 接口模型定義等多個場景中得到廣泛應(yīng)用。
2. 安裝
pip install pydantic pip install pydantic-settings
3. 基礎(chǔ)使用
在開始使用 Pydantic 之前,我們需要了解它的核心概念和基本用法。Pydantic 的核心是通過定義模型類來實現(xiàn)數(shù)據(jù)驗證,這些模型類繼承自 BaseModel。
3.1 創(chuàng)建基礎(chǔ)模型
基礎(chǔ)模型是 Pydantic 中最常用的功能。通過繼承 BaseModel 類,我們可以定義數(shù)據(jù)結(jié)構(gòu)和類型約束。每個字段都可以使用 Python 的類型注解來指定其類型,這些類型會在數(shù)據(jù)驗證時被強制執(zhí)行。
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class User(BaseModel):
id: int
username: str
email: str
full_name: Optional[str] = None # 可選字段
created_at: datetime = datetime.now() # 默認值
# 創(chuàng)建實例
user = User(
id=1,
username="john_doe",
email="john@example.com"
)
# 訪問數(shù)據(jù)
print(user.username) # 輸出: john_doe
# 轉(zhuǎn)換為字典
user_dict = user.model_dump()
字段定義說明:
- id: int - 必填的整數(shù)字段
- username: str - 必填的字符串字段
- email: str - 必填的郵箱字段
- full_name: Optional[str] - 可選的字符串字段,可以為 None
- created_at: datetime - 帶默認值的日期時間字段
3.2 數(shù)據(jù)驗證
Pydantic 的數(shù)據(jù)驗證是自動進行的,當(dāng)創(chuàng)建模型實例時,輸入數(shù)據(jù)會自動根據(jù)定義的類型進行驗證和轉(zhuǎn)換。如果驗證失敗,Pydantic 會拋出詳細的 ValidationError 異常。
from pydantic import BaseModel, EmailStr, ValidationError
class UserRegistration(BaseModel):
username: str
email: EmailStr
age: int
try:
# 嘗試創(chuàng)建無效數(shù)據(jù)
user = UserRegistration(
username="john",
email="invalid-email", # 無效郵箱
age="not_a_number" # 無效年齡
)
except ValidationError as e:
print("驗證錯誤:")
for error in e.errors():
print(f"- {error['loc'][0]}: {error['msg']}")
當(dāng)驗證失敗時,錯誤信息會包含:
- 具體是哪個字段驗證失敗
- 失敗的原因
- 期望的數(shù)據(jù)類型
- 實際接收到的數(shù)據(jù)類型
3.3 嵌套模型
在實際應(yīng)用中,數(shù)據(jù)結(jié)構(gòu)往往是嵌套的。Pydantic 完全支持模型嵌套,這使得我們可以構(gòu)建復(fù)雜的數(shù)據(jù)結(jié)構(gòu),同時保持數(shù)據(jù)驗證的嚴謹性。
from typing import List
class Address(BaseModel):
street: str
city: str
country: str
class User(BaseModel):
name: str
addresses: List[Address]
# 使用嵌套模型
user = User(
name="John Doe",
addresses=[
{"street": "123 Main St", "city": "Boston", "country": "USA"},
{"street": "456 Park Ave", "city": "New York", "country": "USA"}
]
)
嵌套模型的優(yōu)勢:
- 保持數(shù)據(jù)結(jié)構(gòu)的層次清晰
- 支持復(fù)雜的數(shù)據(jù)驗證邏輯
- 方便數(shù)據(jù)的序列化和反序列化
4. 常用驗證規(guī)則
Pydantic 提供了豐富的驗證規(guī)則,可以滿足各種復(fù)雜的數(shù)據(jù)驗證需求。這些規(guī)則可以組合使用,構(gòu)建出強大的驗證邏輯。
4.1 基礎(chǔ)驗證規(guī)則
Field 類是 Pydantic 提供的字段定義工具,它允許我們?yōu)樽侄翁砑痈鞣N驗證規(guī)則和元數(shù)據(jù)。通過 Field,我們可以定義字段的約束條件、默認值和描述信息。
from pydantic import BaseModel, Field, EmailStr, HttpUrl, constr
class User(BaseModel):
# 字符串驗證
name: str = Field(..., min_length=2, max_length=50) # 必填,長度2-50
username: str = Field(..., pattern="^[a-zA-Z0-9_-]+$") # 只允許字母、數(shù)字、下劃線和橫杠
# 數(shù)值驗證
age: int = Field(..., ge=0, le=120) # 大于等于0,小于等于120
score: float = Field(..., gt=0, lt=100) # 大于0,小于100
# 特殊類型驗證
email: EmailStr # 郵箱驗證
website: HttpUrl # URL驗證
# 可選字段
description: str | None = Field(None, max_length=1000) # 可選,最大長度1000
驗證規(guī)則說明:
- min_length/max_length: 控制字符串長度
- pattern: 使用正則表達式驗證字符串格式
- ge/le: 大于等于/小于等于
- gt/lt: 大于/小于
4.2 列表驗證
from typing import List
class Order(BaseModel):
# 列表長度驗證
items: List[str] = Field(..., min_items=1, max_items=10)
# 列表元素唯一性驗證
tags: List[str] = Field(..., unique_items=True)
# 價格必須為正數(shù)的列表
prices: List[float] = Field(..., gt=0)
4.3 自定義驗證器
from pydantic import BaseModel, model_validator, field_validator
from datetime import datetime
class Order(BaseModel):
order_id: str
created_at: datetime
total_amount: float
items_count: int
# 字段級驗證器
@field_validator('order_id')
def validate_order_id(cls, v):
if not v.startswith('ORD-'):
return f'ORD-{v}'
return v
# 模型級驗證器
@model_validator(mode='after')
def validate_total(self):
if self.total_amount <= 0 and self.items_count > 0:
raise ValueError('Total amount must be positive when items exist')
return self
4.4 條件驗證
from typing import Optional
from pydantic import BaseModel, Field, model_validator
class Product(BaseModel):
name: str
price: float
discount: Optional[float] = None
final_price: Optional[float] = None
@model_validator(mode='after')
def calculate_final_price(self):
if self.discount is not None:
if not 0 <= self.discount <= 1:
raise ValueError('Discount must be between 0 and 1')
self.final_price = self.price * (1 - self.discount)
else:
self.final_price = self.price
return self
4.5 常用驗證類型
from pydantic import BaseModel, Field, EmailStr, HttpUrl, conint, confloat, constr
class UserProfile(BaseModel):
# 受約束的字符串
username: constr(min_length=3, max_length=20, pattern="^[a-zA-Z0-9_]+$")
# 受約束的整數(shù)
age: conint(ge=0, le=120)
# 受約束的浮點數(shù)
height: confloat(ge=0, le=300)
# 枚舉選擇
status: str = Field(..., pattern="^(active|inactive|pending)$")
# 布爾值
is_active: bool = True
這些驗證規(guī)則涵蓋了日常開發(fā)中最常見的數(shù)據(jù)驗證場景。通過組合使用這些規(guī)則,可以構(gòu)建出復(fù)雜的數(shù)據(jù)驗證邏輯。記住幾個要點:
- Field(…) 中的 … 表示該字段必填
- 使用 Optional 或 | None 表示可選字段
- 驗證器分為字段級 (field_validator) 和模型級 (model_validator)
- 可以組合多個驗證規(guī)則
- 驗證規(guī)則的順序: 先定義字段,再添加驗證規(guī)則
- 驗證規(guī)則的執(zhí)行順序: 先定義的規(guī)則先執(zhí)行
5. 實際應(yīng)用示例
5.1 API 請求驗證
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = False
@app.post("/items/")
async def create_item(item: Item):
return item
5.2 配置管理
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
database_url: str
api_key: str
debug: bool = False
model_config = SettingsConfigDict(env_file='.env')
# 從環(huán)境變量加載配置
settings = Settings()
6. 小技巧
6.1. 數(shù)據(jù)轉(zhuǎn)換:
# 字典轉(zhuǎn)模型
data = {"name": "John", "age": "25"} # 注意 age 是字符串
user = User.model_validate(data) # 推薦使用 model_validate 而不是 parse_obj
# 模型轉(zhuǎn) JSON
json_str = user.model_dump_json() # 推薦使用 model_dump_json 而不是 json()
# 模型轉(zhuǎn)字典
user_dict = user.model_dump() # 推薦使用 model_dump 而不是 dict()
# 模型轉(zhuǎn) JSON 字符串(帶縮進)
json_str = user.model_dump_json(indent=4)
# JSON 字符串轉(zhuǎn)模型
user = User.model_validate_json(json_str)
6.2 錯誤處理:
try:
user = User(name="John", age="invalid")
except ValidationError as e:
print("數(shù)據(jù)無效:", e)到此這篇關(guān)于Python Pydantic數(shù)據(jù)驗證的實現(xiàn)的文章就介紹到這了,更多相關(guān)Python Pydantic數(shù)據(jù)驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytest用例間參數(shù)傳遞的兩種實現(xiàn)方式示例
pytest提供了許多運行命令以供定制化運行某一類測試用例或者某個測試用例等,下面這篇文章主要給大家介紹了關(guān)于pytest用例間參數(shù)傳遞的兩種實現(xiàn)方式,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2021-12-12
使用Python的Dataframe取兩列時間值相差一年的所有行方法
今天小編就為大家分享一篇使用Python的Dataframe取兩列時間值相差一年的所有行方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
pytorch實現(xiàn)mnist數(shù)據(jù)集的圖像可視化及保存
今天小編就為大家分享一篇pytorch實現(xiàn)mnist數(shù)據(jù)集的圖像可視化及保存,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Windows 下python3.8環(huán)境安裝教程圖文詳解
這篇文章主要介紹了Windows 下python3.8環(huán)境安裝教程圖文詳解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03

