快轉到主要內容
  1. 教學文章/

Python 資料驗證小幫手:Pydantic

·4 分鐘· loading · loading · ·
Python Pydantic Data Validation
每日拍拍
作者
每日拍拍
科學家 X 科技宅宅
目錄
Python 學習 - 本文屬於一個選集。
§ 14: 本文

為什麼需要 Pydantic?
#

寫 Python 專案時,你是不是常常遇到這些狀況:

  • 從 API 拿到一包 JSON 資料,結果某個欄位是 null 導致程式直接爆炸?
  • 明明要傳整數,結果使用者傳了字串 "123",程式跑一半才發現型別不對?
  • 設定檔裡的參數拼錯字或格式錯誤,debug 半天才找到問題?
  • 每次都要手動寫一堆 if 判斷來驗證資料?

這時候你就需要 Pydantic!它是一個強大的資料驗證與設定管理套件,能在執行階段自動驗證資料型別、格式,還支援自動型別轉換。最棒的是,它跟 Python 的型別提示(Type Hints)完美整合,讓你寫程式時就能享受 IDE 的自動補全與型別檢查!

安裝 Pydantic
#

pip install pydantic

如果要用於設定檔管理,建議加裝 pydantic-settings

pip install pydantic-settings

基本用法
#

1. 定義資料模型
#

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    email: str
    age: int
    is_active: bool = True  # 預設值

# 建立 User 物件
user = User(id=1, name="拍拍君", email="ppy@example.com", age=25)
print(user)
# User(id=1, name='拍拍君', email='ppy@example.com', age=25, is_active=True)

# 存取屬性
print(user.name)  # 拍拍君
print(user.age)   # 25

只要繼承 BaseModel,定義好欄位型別,Pydantic 就會自動幫你驗證!

2. 自動型別轉換
#

# 即使傳入字串,Pydantic 會自動轉換成整數
user = User(id="123", name="拍拍醬", email="ppj@example.com", age="30")
print(user.id)   # 123 (int)
print(user.age)  # 30 (int)

3. 驗證錯誤處理
#

from pydantic import ValidationError

try:
    user = User(id="abc", name="測試", email="test@example.com", age=25)
except ValidationError as e:
    print(e)

如果傳入的資料無法轉換或驗證失敗,會拋出 ValidationError,錯誤訊息非常詳細,告訴你哪個欄位出問題!

進階功能
#

1. 欄位驗證器
#

from pydantic import BaseModel, field_validator

class User(BaseModel):
    name: str
    age: int

    @field_validator('age')
    def check_age(cls, v):
        if v < 0 or v > 150:
            raise ValueError('年齡必須在 0-150 之間')
        return v

# 這會拋出驗證錯誤
try:
    user = User(name="測試", age=200)
except ValidationError as e:
    print(e)

2. 從 JSON 讀取
#

import json

# JSON 字串
json_data = '{"id": 1, "name": "拍拍君", "email": "ppy@example.com", "age": 25}'

# 直接從 JSON 建立物件
user = User.model_validate_json(json_data)
print(user)

# 轉回 JSON
print(user.model_dump_json())

3. 巢狀模型
#

from typing import List

class Address(BaseModel):
    street: str
    city: str
    zip_code: str

class User(BaseModel):
    name: str
    addresses: List[Address]

user = User(
    name="拍拍君",
    addresses=[
        {"street": "忠孝東路", "city": "台北", "zip_code": "100"},
        {"street": "中山路", "city": "新竹", "zip_code": "300"}
    ]
)

print(user.addresses[0].city)  # 台北

用 Pydantic 管理設定檔
#

Pydantic 最強大的應用之一就是取代傳統的 JSON/YAML 設定檔!

傳統作法:用 JSON 設定檔
#

import json

# config.json
# {
#   "api_key": "my_secret_key",
#   "max_connections": 10,
#   "timeout": 30
# }

with open("config.json") as f:
    config = json.load(f)

api_key = config["api_key"]
max_connections = config["max_connections"]  # 沒有型別檢查,可能是字串!

問題:

  • 沒有型別檢查(可能 max_connections 是字串 "10"
  • 拼錯字直到執行時才發現
  • 沒有預設值機制
  • 沒有驗證(例如 timeout 不能是負數)

Pydantic 作法:用 Python 定義設定
#

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    api_key: str
    max_connections: int = 10
    timeout: int = 30
    debug: bool = False

    class Config:
        env_file = '.env'  # 支援從 .env 讀取

settings = Settings()
print(settings.api_key)
print(settings.max_connections)  # 保證是 int

建立 .env 檔案:

API_KEY=my_secret_key
MAX_CONNECTIONS=20
DEBUG=true

執行程式時,Pydantic 會自動從環境變數或 .env 檔案讀取設定!

Pydantic vs JSON/YAML 設定檔
#

特性 JSON/YAML Pydantic
型別安全 ❌ 沒有 ✅ 自動驗證與轉換
IDE 支援 ❌ 無自動補全 ✅ 完整型別提示與補全
預設值 ⚠️ 需手動處理 ✅ 直接在欄位定義
驗證邏輯 ❌ 需自己寫 ✅ 內建 validator
錯誤訊息 ⚠️ KeyError 不清楚 ✅ 詳細的驗證錯誤
環境變數整合 ❌ 需額外處理 ✅ 原生支援
學習曲線 ✅ 簡單 ⚠️ 需熟悉 Python 型別
人類可讀性 ✅ 非技術人員也能改 ⚠️ 需要懂 Python

使用建議
#

適合用 Pydantic 的場景:

  • Python 專案內部設定
  • API 資料驗證(FastAPI 就是用 Pydantic!)
  • 複雜的驗證邏輯
  • 需要型別安全的專案
  • 與環境變數整合

適合用 JSON/YAML 的場景:

  • 需要非程式設計師修改設定
  • 跨語言的設定檔
  • 簡單的靜態設定
  • 需要序列化儲存的資料

小技巧
#

  • Pydantic v2(2023 年後)效能大幅提升,建議使用最新版本
  • 搭配 FastAPI 使用超順暢(FastAPI 內建就用 Pydantic)
  • 可用 model_dump() 轉成 dict,model_dump_json() 轉成 JSON
  • 支援 OptionalUnionListDict 等複雜型別
  • 可以用 Field() 加入更多驗證規則,例如字串長度、數值範圍

結語
#

Pydantic 讓拍拍君寫 Python 專案時再也不用擔心資料格式問題!自動驗證、型別轉換、完整的 IDE 支援,大大減少了 debug 時間。尤其是在開發 API 或處理外部資料時,Pydantic 幾乎是必裝套件!

如果你的專案還在用 JSON/YAML 手動解析設定,不妨試試看 Pydantic,保證讓你愛不釋手!

延伸閱讀
#

Python 學習 - 本文屬於一個選集。
§ 14: 本文

相關文章

科學計算:數值積分
·5 分鐘· loading · loading
Python Numpy Scipy Numerical Methods Numerical Integral
Python: 我需要進度條! tqdm
·3 分鐘· loading · loading
Python Tqdm Data Science
讓你的終端機華麗變身:Rich 套件教學
·2 分鐘· loading · loading
Python Rich Cli
管理秘密環境變數 python-dotenv
·1 分鐘· loading · loading
Python Dotenv
開發的好習慣 Unit Test
·5 分鐘· loading · loading
Python Pytest Ci Unittest
擺脫「在我的電腦上可以跑」的魔咒:Nix Package Manager 入門
·5 分鐘· loading · loading
Nix