Python Pydantic數(shù)據(jù)驗(yàn)證的實(shí)現(xiàn)
1. 什么是 Pydantic?
Pydantic 是一個(gè)功能強(qiáng)大的 Python 數(shù)據(jù)驗(yàn)證庫(kù),它通過 Python 類型注解實(shí)現(xiàn)快速的數(shù)據(jù)驗(yàn)證和轉(zhuǎn)換。它不僅提供了全面的類型驗(yàn)證、自動(dòng)數(shù)據(jù)轉(zhuǎn)換和詳細(xì)的錯(cuò)誤處理機(jī)制,還具有基于 Rust 實(shí)現(xiàn)的高性能核心驗(yàn)證器。憑借其優(yōu)秀的 IDE 支持和可擴(kuò)展性,Pydantic 在 FastAPI 等 Web 框架、配置管理、數(shù)據(jù)序列化以及 API 接口模型定義等多個(gè)場(chǎng)景中得到廣泛應(yīng)用。
2. 安裝
pip install pydantic pip install pydantic-settings
3. 基礎(chǔ)使用
在開始使用 Pydantic 之前,我們需要了解它的核心概念和基本用法。Pydantic 的核心是通過定義模型類來實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證,這些模型類繼承自 BaseModel。
3.1 創(chuàng)建基礎(chǔ)模型
基礎(chǔ)模型是 Pydantic 中最常用的功能。通過繼承 BaseModel 類,我們可以定義數(shù)據(jù)結(jié)構(gòu)和類型約束。每個(gè)字段都可以使用 Python 的類型注解來指定其類型,這些類型會(huì)在數(shù)據(jù)驗(yàn)證時(shí)被強(qiáng)制執(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() # 默認(rèn)值 # 創(chuàng)建實(shí)例 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 - 帶默認(rèn)值的日期時(shí)間字段
3.2 數(shù)據(jù)驗(yàn)證
Pydantic 的數(shù)據(jù)驗(yàn)證是自動(dòng)進(jìn)行的,當(dāng)創(chuàng)建模型實(shí)例時(shí),輸入數(shù)據(jù)會(huì)自動(dòng)根據(jù)定義的類型進(jìn)行驗(yàn)證和轉(zhuǎn)換。如果驗(yàn)證失敗,Pydantic 會(huì)拋出詳細(xì)的 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("驗(yàn)證錯(cuò)誤:") for error in e.errors(): print(f"- {error['loc'][0]}: {error['msg']}")
當(dāng)驗(yàn)證失敗時(shí),錯(cuò)誤信息會(huì)包含:
- 具體是哪個(gè)字段驗(yàn)證失敗
- 失敗的原因
- 期望的數(shù)據(jù)類型
- 實(shí)際接收到的數(shù)據(jù)類型
3.3 嵌套模型
在實(shí)際應(yīng)用中,數(shù)據(jù)結(jié)構(gòu)往往是嵌套的。Pydantic 完全支持模型嵌套,這使得我們可以構(gòu)建復(fù)雜的數(shù)據(jù)結(jié)構(gòu),同時(shí)保持?jǐn)?shù)據(jù)驗(yàn)證的嚴(yán)謹(jǐn)性。
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ǐn)?shù)據(jù)結(jié)構(gòu)的層次清晰
- 支持復(fù)雜的數(shù)據(jù)驗(yàn)證邏輯
- 方便數(shù)據(jù)的序列化和反序列化
4. 常用驗(yàn)證規(guī)則
Pydantic 提供了豐富的驗(yàn)證規(guī)則,可以滿足各種復(fù)雜的數(shù)據(jù)驗(yàn)證需求。這些規(guī)則可以組合使用,構(gòu)建出強(qiáng)大的驗(yàn)證邏輯。
4.1 基礎(chǔ)驗(yàn)證規(guī)則
Field 類是 Pydantic 提供的字段定義工具,它允許我們?yōu)樽侄翁砑痈鞣N驗(yàn)證規(guī)則和元數(shù)據(jù)。通過 Field,我們可以定義字段的約束條件、默認(rèn)值和描述信息。
from pydantic import BaseModel, Field, EmailStr, HttpUrl, constr class User(BaseModel): # 字符串驗(yàn)證 name: str = Field(..., min_length=2, max_length=50) # 必填,長(zhǎng)度2-50 username: str = Field(..., pattern="^[a-zA-Z0-9_-]+$") # 只允許字母、數(shù)字、下劃線和橫杠 # 數(shù)值驗(yàn)證 age: int = Field(..., ge=0, le=120) # 大于等于0,小于等于120 score: float = Field(..., gt=0, lt=100) # 大于0,小于100 # 特殊類型驗(yàn)證 email: EmailStr # 郵箱驗(yàn)證 website: HttpUrl # URL驗(yàn)證 # 可選字段 description: str | None = Field(None, max_length=1000) # 可選,最大長(zhǎng)度1000
驗(yàn)證規(guī)則說明:
- min_length/max_length: 控制字符串長(zhǎng)度
- pattern: 使用正則表達(dá)式驗(yàn)證字符串格式
- ge/le: 大于等于/小于等于
- gt/lt: 大于/小于
4.2 列表驗(yàn)證
from typing import List class Order(BaseModel): # 列表長(zhǎng)度驗(yàn)證 items: List[str] = Field(..., min_items=1, max_items=10) # 列表元素唯一性驗(yàn)證 tags: List[str] = Field(..., unique_items=True) # 價(jià)格必須為正數(shù)的列表 prices: List[float] = Field(..., gt=0)
4.3 自定義驗(yàn)證器
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 # 字段級(jí)驗(yàn)證器 @field_validator('order_id') def validate_order_id(cls, v): if not v.startswith('ORD-'): return f'ORD-{v}' return v # 模型級(jí)驗(yàn)證器 @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 條件驗(yàn)證
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 常用驗(yàn)證類型
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) # 受約束的浮點(diǎn)數(shù) height: confloat(ge=0, le=300) # 枚舉選擇 status: str = Field(..., pattern="^(active|inactive|pending)$") # 布爾值 is_active: bool = True
這些驗(yàn)證規(guī)則涵蓋了日常開發(fā)中最常見的數(shù)據(jù)驗(yàn)證場(chǎng)景。通過組合使用這些規(guī)則,可以構(gòu)建出復(fù)雜的數(shù)據(jù)驗(yàn)證邏輯。記住幾個(gè)要點(diǎn):
- Field(…) 中的 … 表示該字段必填
- 使用 Optional 或 | None 表示可選字段
- 驗(yàn)證器分為字段級(jí) (field_validator) 和模型級(jí) (model_validator)
- 可以組合多個(gè)驗(yàn)證規(guī)則
- 驗(yàn)證規(guī)則的順序: 先定義字段,再添加驗(yàn)證規(guī)則
- 驗(yàn)證規(guī)則的執(zhí)行順序: 先定義的規(guī)則先執(zhí)行
5. 實(shí)際應(yīng)用示例
5.1 API 請(qǐng)求驗(yàn)證
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 字符串(帶縮進(jìn)) json_str = user.model_dump_json(indent=4) # JSON 字符串轉(zhuǎn)模型 user = User.model_validate_json(json_str)
6.2 錯(cuò)誤處理:
try: user = User(name="John", age="invalid") except ValidationError as e: print("數(shù)據(jù)無效:", e)
到此這篇關(guān)于Python Pydantic數(shù)據(jù)驗(yàn)證的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Pydantic數(shù)據(jù)驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Pycharm中項(xiàng)目解釋器與環(huán)境變量的設(shè)置方法
今天小編就為大家分享一篇在Pycharm中項(xiàng)目解釋器與環(huán)境變量的設(shè)置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python利用matplotlib繪制散點(diǎn)圖的新手教程
這篇文章主要給大家介紹了關(guān)于Python利用matplotlib繪制散點(diǎn)圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python通過keyboard庫(kù)實(shí)現(xiàn)模擬和監(jiān)聽鍵盤
這篇文章主要為大家詳細(xì)介紹了Python如何通過keyboard庫(kù)實(shí)現(xiàn)模擬和監(jiān)聽鍵盤,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-10-10淺談Python數(shù)學(xué)建模之?dāng)?shù)據(jù)導(dǎo)入
數(shù)據(jù)導(dǎo)入是所有數(shù)模編程的第一步,比你想象的更重要。Python 語(yǔ)言中數(shù)據(jù)導(dǎo)入的方法很多。對(duì)于數(shù)學(xué)建模問題編程來說,選擇什么方法最好呢?答案是:沒有最好的,只有最合適的。對(duì)于不同的問題,不同的算法,以及所調(diào)用工具包的不同實(shí)現(xiàn)方法,對(duì)于數(shù)據(jù)就會(huì)有不同的要求2021-06-06pytorch中的squeeze函數(shù)、cat函數(shù)使用
這篇文章主要介紹了pytorch中的squeeze函數(shù)、cat函數(shù)使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05Python3實(shí)現(xiàn)的旋轉(zhuǎn)矩陣圖像算法示例
這篇文章主要介紹了Python3實(shí)現(xiàn)的旋轉(zhuǎn)矩陣圖像算法,涉及Python3列表遍歷、切片轉(zhuǎn)換、矩陣運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2019-04-04