Pydantic:让类型注解真正干活


你有没有遇到过这种情况:从 API 拿到一堆 JSON,结果 age 是字符串 "25"is_active"true"id 居然是 null

以前你得写一堆 if isinstance(...) 来处理。

现在,一个 Pydantic 模型就够了。


原理:类型注解不再是摆设

Python 的类型注解本来只给 IDE 和类型检查器用,运行时完全被忽略。

Pydantic 做了一件事:在运行时把类型注解真正执行起来。

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str
    age: int | None = None

当你创建实例时,Pydantic 会:

  • 逐字段校验类型
  • 能自动转的就转("25"25
  • 转不了的直接报错,告诉你哪个字段、什么值、为什么不对

底层靠的是读取类的 __annotations__,在 __init__ 里拦截数据,走一套校验逻辑。


什么时候该用它

FastAPI 开发 — 这是最大的使用场景。请求参数、响应体全靠 Pydantic 校验,省掉大量手动验证代码。

配置文件加载 — 把 .envyaml 读进来直接变对象,字段写错立刻知道。

外部数据清洗 — 第三方 API 返回的脏数据,过一层模型就干净了。

前后端联调 — 前后端共用一套模型定义,字段对不齐马上暴露。


上手实验

实验 1:类型自动转换

from pydantic import BaseModel

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

u = User(id="1001", name="张三", active="yes")

print(u.id)       # 1001  (int,不是字符串)
print(u.active)   # True (bool,不是字符串)

"1001" 自动变成 int"yes" 自动变成 True


实验 2:校验失败长什么样

try:
    User(id="abc", name="李四", active="可能")
except Exception as e:
    print(e)

输出:

2 validation errors for User
id
  Input should be a valid integer [type=int_parsing, input_value='abc']
active
  Input should be a valid boolean [type=bool_parsing, input_value='可能']

哪个字段、什么值、为什么错,清清楚楚。


实验 3:嵌套模型

class Address(BaseModel):
    city: str
    zip: str

class User(BaseModel):
    name: str
    address: Address

u = User(
    name="王五",
    address={"city": "哈尔滨", "zip": "150000"}
)

print(u.address.city)  # 哈尔滨

字典传进去,自动变成 Address 模型实例。


最后说一句

Pydantic 的本质就一句话:

让类型注解从"文档"变成"规则"。

写模型几乎零成本,但能帮你挡住大部分脏数据。配合 FastAPI,几乎是现在 Python Web 开发的标配了。

更多推荐