跳轉至

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

BaseModel 模型

BaseModel 是 Pydantic 最核心的類別:繼承它、用型別提示宣告欄位,就得到一個在建立時自動驗證資料的模型。本頁說明如何宣告模型、建立物件的幾種方式、必填與選填欄位、型別轉換規則,以及模型物件常用的屬性與方法。

如何宣告一個模型?

from datetime import datetime

from pydantic import BaseModel


class User(BaseModel):
    id: int                       # 必填
    name: str                     # 必填
    email: str | None = None      # 選填,預設 None
    tags: list[str] = []          # 選填,預設空串列(Pydantic 會為每個物件複製一份)
    signup_ts: datetime | None = None


user = User(id=1, name="Alice", signup_ts="2026-10-11T09:30:00")
print(user.signup_ts)  # 2026-10-11 09:30:00(字串已轉成 datetime)
print(user.tags)       # []

規則很簡單:沒有預設值的欄位就是必填;有預設值(包含 None)的欄位是選填。

可變預設值是安全的

一般 Python 類別寫 tags: list = [] 會讓所有物件共用同一個串列;Pydantic 會為每個物件深複製(deep copy)預設值,所以 = [] 是安全的寫法。

建立模型物件有哪幾種方式?

方式 適用情境
User(id=1, name="Alice") 在程式碼中直接建立,參數用關鍵字傳入
User.model_validate({"id": 1, "name": "Alice"}) 資料已經是 dict(例如 json.load 的結果)
User.model_validate_json('{"id": 1, "name": "Alice"}') 資料是 JSON 字串或 bytes,直接解析+驗證,比先 json.loads 更快
from pydantic import BaseModel


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


raw = '{"id": 7, "name": "Bob"}'
user = User.model_validate_json(raw)
print(user.id, user.name)  # 7 Bob

Pydantic 會自動轉換型別嗎?

會。預設的「寬鬆模式」(lax mode)會做合理且不遺失資訊的轉換:

欄位型別 會被接受的輸入 會被拒絕的輸入
int 3、"3"、3.0 "3.5"、3.5、"abc"
float 1.5、"1.5"、2 "abc"
bool True、"true"、"yes"、"1"、1 "maybe"、2
str "abc" 123(數字不會自動轉成字串)
datetime ISO 8601 字串、Unix 時間戳 "明天"

注意 3.5 傳給 int 會失敗,因為轉換會遺失小數部分。需要完全不轉換時可以開啟嚴格模式(strict mode),見 model_config 模型設定。

驗證失敗時會怎樣?

建立物件時只要有任一欄位不合法,就會丟出 pydantic.ValidationError,而且會一次列出所有錯誤,而不是只回報第一個:

from pydantic import BaseModel, ValidationError


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


try:
    User(id="abc")
except ValidationError as e:
    print(e)

輸出會指出 id 不是合法整數、name 欄位缺少。如何讀懂與處理這些錯誤,見 ValidationError 錯誤處理。

模型物件有哪些常用屬性與方法?

V2 的模型方法一律以 model_ 開頭,避免和你自己的欄位名稱衝突:

方法/屬性 作用
model_dump() 轉成 dict
model_dump_json() 轉成 JSON 字串
model_copy(update={...}) 複製物件,可同時修改部分欄位
model_fields_set 建立時「明確傳入」的欄位名稱集合
User.model_fields 類別上的欄位定義資訊
User.model_json_schema() 產生 JSON Schema
from pydantic import BaseModel


class User(BaseModel):
    id: int
    name: str
    role: str = "member"


user = User(id=1, name="Alice")
admin = user.model_copy(update={"role": "admin"})

print(user.model_dump())     # {'id': 1, 'name': 'Alice', 'role': 'member'}
print(admin.role)            # admin
print(user.model_fields_set) # {'id', 'name'}(role 用的是預設值)

修改屬性時不會重新驗證

預設情況下 user.id = "abc" 不會報錯。需要在賦值時也驗證,請在 model_config 設定 validate_assignment=True;需要不可變物件則設定 frozen=True,見 model_config 模型設定。

推薦影音

pixegami:Pydantic 入門教學

簡述:約 11 分鐘,從「Python 動態型別帶來的問題」切入,依序示範建立模型、驗證資料、自訂欄位驗證、JSON 序列化,最後比較 Pydantic 與 dataclass,很快就能建立對 BaseModel 的整體印象。

相關資料