跳轉至

建立 2026-10-11 更新 2026-10-11

為什麼需要 Pydantic

Python 需要 Pydantic,是因為型別提示(type hints)在執行時不會被檢查:宣告 age: int 之後,傳進字串 "abc" 程式照樣執行,錯誤要到很後面才爆開。Pydantic 在資料「進門」的那一刻依型別驗證並轉換,讓壞資料在邊界就被擋下,而不是在商業邏輯深處造成難以追查的 bug。

型別提示、型別檢查、資料驗證差在哪?

這三個詞常被混用,但負責的時間點與對象完全不同:

名稱 誰來做 什麼時候 能擋住什麼
型別提示(type hints) 你寫在程式碼上 不執行任何檢查 什麼都擋不住,只是說明與 IDE 提示
型別檢查(type checking) mypy、Pyright 等工具 開發階段(靜態分析) 自己程式碼裡的型別錯誤
資料驗證(data validation) Pydantic 執行階段 來自外部、事先無法預知的資料

關鍵在最後一列:API 請求、JSON 檔、環境變數、資料庫查詢結果、LLM 回傳的文字,都是執行時才知道內容的資料,靜態型別檢查器看不到,只有執行期驗證能處理。

沒有 Pydantic 時會發生什麼事?

只用型別提示時,錯誤資料會一路往下流:

from dataclasses import dataclass


@dataclass
class Order:
    quantity: int
    price: float


order = Order(quantity="3", price="19.9")  # 不會報錯!
total = order.quantity * order.price  # TypeError:字串不能乘字串

錯誤發生在計算總價那一行,而不是資料進來的地方。真實專案中這兩行可能相隔好幾個檔案,追查成本很高。

改用 Pydantic 後,同樣的資料會在建立物件時就被驗證並轉成正確型別:

from pydantic import BaseModel


class Order(BaseModel):
    quantity: int
    price: float


order = Order(quantity="3", price="19.9")
print(order.quantity * order.price)  # 59.699999999999996,型別已轉成 int 與 float

如果傳入 quantity="three",Pydantic 會立刻丟出 ValidationError,並指出是哪個欄位、為什麼不合法。

Pydantic 適合用在哪些地方?

  • Web API:FastAPI 用 Pydantic 模型定義請求與回應格式,自動驗證並產生 OpenAPI 文件。
  • 設定管理:pydantic-settings 從環境變數與 .env 讀取設定,型別錯誤在啟動時就發現。
  • 資料管線:讀取 CSV、JSON、外部 API 回應時,先驗證再處理。
  • LLM 結構化輸出:要求模型輸出符合 JSON Schema 的資料,再用 Pydantic 驗證,避免手動解析字串。

什麼時候不需要 Pydantic?

資料完全由自己的程式產生、不跨越任何邊界時,驗證是多餘的成本。這時用標準函式庫的 dataclasses 或一般類別即可。原則是:在系統邊界驗證,在內部信任型別。

推薦影音

Corey Schafer:型別提示、型別檢查與資料驗證的差別

簡述:用實例說明三者各自負責什麼,以及為什麼有了 mypy 仍然需要 Pydantic,正好對應本頁第一節。

ArjanCodes:為什麼真實專案需要 Pydantic

簡述:從軟體設計角度示範欄位驗證、模型驗證、自訂序列化與 FastAPI 整合,適合想知道「Pydantic 在大型專案中扮演什麼角色」的讀者。

相關資料