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 接口模型定義等多個場景中得到廣泛應用。
2. 安裝
pip install pydantic pip install pydantic-settings
3. 基礎使用
在開始使用 Pydantic 之前,我們需要了解它的核心概念和基本用法。Pydantic 的核心是通過定義模型類來實現(xiàn)數(shù)據(jù)驗證,這些模型類繼承自 BaseModel。
3.1 創(chuàng)建基礎模型
基礎模型是 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ù)驗證是自動進行的,當創(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']}")
當驗證失敗時,錯誤信息會包含:
- 具體是哪個字段驗證失敗
- 失敗的原因
- 期望的數(shù)據(jù)類型
- 實際接收到的數(shù)據(jù)類型
3.3 嵌套模型
在實際應用中,數(shù)據(jù)結(jié)構(gòu)往往是嵌套的。Pydantic 完全支持模型嵌套,這使得我們可以構(gòu)建復雜的數(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)的層次清晰
- 支持復雜的數(shù)據(jù)驗證邏輯
- 方便數(shù)據(jù)的序列化和反序列化
4. 常用驗證規(guī)則
Pydantic 提供了豐富的驗證規(guī)則,可以滿足各種復雜的數(shù)據(jù)驗證需求。這些規(guī)則可以組合使用,構(gòu)建出強大的驗證邏輯。
4.1 基礎驗證規(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)建出復雜的數(shù)據(jù)驗證邏輯。記住幾個要點:
- Field(…) 中的 … 表示該字段必填
- 使用 Optional 或 | None 表示可選字段
- 驗證器分為字段級 (field_validator) 和模型級 (model_validator)
- 可以組合多個驗證規(guī)則
- 驗證規(guī)則的順序: 先定義字段,再添加驗證規(guī)則
- 驗證規(guī)則的執(zhí)行順序: 先定義的規(guī)則先執(zhí)行
5. 實際應用示例
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)
到此這篇關于Python Pydantic數(shù)據(jù)驗證的實現(xiàn)的文章就介紹到這了,更多相關Python Pydantic數(shù)據(jù)驗證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
在Pycharm中項目解釋器與環(huán)境變量的設置方法
今天小編就為大家分享一篇在Pycharm中項目解釋器與環(huán)境變量的設置方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python通過keyboard庫實現(xiàn)模擬和監(jiān)聽鍵盤
這篇文章主要為大家詳細介紹了Python如何通過keyboard庫實現(xiàn)模擬和監(jiān)聽鍵盤,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下2024-10-10淺談Python數(shù)學建模之數(shù)據(jù)導入
數(shù)據(jù)導入是所有數(shù)模編程的第一步,比你想象的更重要。Python 語言中數(shù)據(jù)導入的方法很多。對于數(shù)學建模問題編程來說,選擇什么方法最好呢?答案是:沒有最好的,只有最合適的。對于不同的問題,不同的算法,以及所調(diào)用工具包的不同實現(xiàn)方法,對于數(shù)據(jù)就會有不同的要求2021-06-06pytorch中的squeeze函數(shù)、cat函數(shù)使用
這篇文章主要介紹了pytorch中的squeeze函數(shù)、cat函數(shù)使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05Python3實現(xiàn)的旋轉(zhuǎn)矩陣圖像算法示例
這篇文章主要介紹了Python3實現(xiàn)的旋轉(zhuǎn)矩陣圖像算法,涉及Python3列表遍歷、切片轉(zhuǎn)換、矩陣運算等相關操作技巧,需要的朋友可以參考下2019-04-04