Pydantic 是一个 Python 库,核心是做数据验证、设置管理和数据转换
想象一下,你开了一家店(你的程序),顾客(其他代码或用户)会给你递纸条(数据),纸条上写着他们要买的东西。
- 问题: 纸条可能写得很乱!比如“苹果5个”(正确),但也可能是“苹果五”、“苹果5”、“Apples 5”,甚至“香蕉5”(写错了商品)。你需要把这些纸条整理成清晰的订单。
- Pydantic 是干嘛的? 它就像你店里一个超级负责、眼尖又有点强迫症的订单检查员 + 格式转换员。
- 检查订单对不对(数据验证): 它会仔细看每张纸条:
- 商品名写对了吗?(比如必须是“苹果”、“香蕉”,不能是“大象”)
- 数量写的是数字吗?(“5”可以,“五”不行)
- 顾客名字写了吗?(如果要求必须写的话)
- 地址格式对吗?(如果是邮寄订单)
- 自动整理成标准格式(数据解析/转换): 对于能修正的小错误,它会自动帮你改好:
- 把“五”自动转成数字
5
。 - 把“Apples”自动转成你规定的“苹果”。
- 把字符串
"5"
自动转成整数5
。
- 把“五”自动转成数字
- 输出清晰订单(数据建模): 最后,它会把通过检查并整理好的信息,按照你预先定义好的、非常工整的“订单模板”(Python 类)打印出来给你(生成一个 Python 对象)。这个对象里的数据你绝对可以放心用,都是符合要求的。
- 检查订单对不对(数据验证): 它会仔细看每张纸条:
核心价值:
- 让你的代码更健壮: 脏数据、错误数据在源头就被拦住或修正了,程序不会因为收到一个
"五"
当数量就崩溃。 - 让你的代码更清晰: 用 Python 类明确定义数据长什么样(字段名、类型、是否必填、默认值等),一目了然。
- 节省大量样板代码: 你不用自己写一堆
if ... else ...
来检查每个字段的类型、范围、是否为空等等。Pydantic 帮你自动搞定。 - 和现代 Python 绝配: 大量使用 Python 的“类型提示”,让 IDE 更聪明,代码更好读。
举例说明:
场景 1:用户注册信息验证
假设你要处理用户提交的注册信息(用户名、邮箱、年龄)。
-
定义“订单模板”(Pydantic 模型):
from pydantic import BaseModel, EmailStr, conint # 导入必要的模块和类型class UserRegistration(BaseModel):username: str # 用户名必须是字符串email: EmailStr # 邮箱必须是有效的邮箱格式字符串age: conint(gt=0) # 年龄必须是大于0的整数is_active: bool = True # 是否激活,布尔值,默认True(可选字段)
username
: 字符串就行。email
: 用EmailStr
,Pydantic 会检查它是不是一个有效的邮箱格式(有@
,有域名等)。age
: 用conint(gt=0)
,表示必须是整数且大于0。is_active
: 布尔值,并且有默认值True
(如果用户没提供,就用这个值)。
-
“顾客”递交纸条(数据):
# 假设从网页表单收到这些数据(通常会是字典或 JSON) input_data = {"username": "小白Python","email": "xiaobai@example.com", # 格式正确"age": 25,# "is_active" 没提供,将使用默认值 True }# 也可能收到有问题的数据 bad_data = {"username": "小白Python","email": "这不是邮箱", # 无效邮箱格式"age": -5, # 负数,不符合 >0 }
-
交给“检查员”Pydantic 处理:
# 处理好的数据 try:user = UserRegistration(**input_data) # 把字典数据传给模型print("注册信息有效!")print(f"用户名: {user.username}")print(f"邮箱: {user.email}") # 已经是标准的字符串print(f"年龄: {user.age}") # 已经是整数 25print(f"激活状态: {user.is_active}") # 使用默认值 True except Exception as e:print(f"注册信息有误: {e}")# 处理有问题的数据 try:invalid_user = UserRegistration(**bad_data) except Exception as e:print(f"错误捕获!原因: {e}")
输出:
注册信息有效! 用户名: 小白Python 邮箱: xiaobai@example.com 年龄: 25 激活状态: True错误捕获!原因: 2 validation errors for UserRegistration emailvalue is not a valid email address: The email address is not valid. Input: "这不是邮箱" [type=value_error, input_value='这不是邮箱', input_type=str] ageInput should be greater than 0 [type=greater_than, input_value=-5, input_type=int]
看!Pydantic 干了什么:
- 对
input_data
:- 验证了
email
格式有效。 - 验证了
age
25 是大于 0 的整数。 is_active
没提供,用了默认值True
。- 自动创建了一个
user
对象,里面的属性都是正确的类型(age
是int
,is_active
是bool
)。
- 验证了
- 对
bad_data
:- 发现
email
格式无效。 - 发现
age
是负数,不符合>0
。 - 直接抛出一个非常详细的错误 (
ValidationError
),明确告诉你哪两个字段错了,为什么错,输入的值是什么。你的代码可以捕获这个错误,给用户友好的提示。
- 发现
- 对
场景 2:更复杂的嵌套数据(比如配置信息或 API 响应)
假设你要处理一个 JSON 配置,它包含数据库连接信息和一些特性开关。
-
定义模型:
from pydantic import BaseModel, AnyUrlclass DatabaseConfig(BaseModel):host: strport: int = 5432 # 默认端口 5432 (PostgreSQL)user: strpassword: strname: strclass FeatureFlags(BaseModel):dark_mode: bool = Falseexperimental: bool = Falseclass AppConfig(BaseModel):app_name: str = "My Awesome App"debug: bool = Falsedatabase: DatabaseConfig # 嵌套 DatabaseConfig 模型!features: FeatureFlags # 嵌套 FeatureFlags 模型!
-
原始 JSON 数据 (可能来自 config.json 文件):
{"debug": true,"database": {"host": "db.example.com","user": "admin","password": "secret123","name": "prod_db"},"features": {"dark_mode": true} }
- 注意:
database.port
没提供,将用默认值5432
。 features.experimental
没提供,将用默认值False
。app_name
没提供,将用默认值"My Awesome App"
。
- 注意:
-
用 Pydantic 加载和验证:
import json# 读取 JSON 文件 with open('config.json') as f:json_data = json.load(f)# 用 Pydantic 解析和验证 config = AppConfig(**json_data)# 现在可以安全方便地访问配置了! print(config.app_name) # 输出: My Awesome App print(config.debug) # 输出: True print(config.database.host) # 输出: db.example.com print(config.database.port) # 输出: 5432 (使用了默认值) print(config.features.dark_mode) # 输出: True print(config.features.experimental) # 输出: False (使用了默认值)
Pydantic 干了什么:
- 自动将 JSON 字典(及其嵌套字典)转换成
AppConfig
、DatabaseConfig
、FeatureFlags
的嵌套对象。 - 验证了所有字段的类型(
debug
是bool
,database.host
是str
等)。 - 对缺失的字段应用了默认值(
app_name
,database.port
,features.experimental
)。 - 现在
config
对象就像访问普通 Python 对象属性一样访问配置,类型安全且结构清晰。
- 自动将 JSON 字典(及其嵌套字典)转换成
总结一下:
- Pydantic 是一个 Python 库,核心是做数据验证、设置管理和数据转换。
- 它让你用 Python 类(继承
BaseModel
)来清晰定义数据应该长什么样(字段名、类型、是否必填、默认值、额外规则如邮箱格式、数值范围等)。 - 你把原始数据(字典、JSON 字符串等)丢给它,它会:
- 严格检查数据是否符合你定义的要求。
- 尝试自动把数据转换成正确的类型(比如字符串
"5"
转成整数5
)。 - 如果数据有错,给你非常详细的错误报告。
- 如果数据没问题,给你一个符合你定义的类实例(对象),里面的数据可以直接放心使用。
- 好处:代码更健壮(少崩溃)、更清晰(数据结构一目了然)、更少写验证代码(Pydantic 帮你干了脏活累活)。
它在哪最常用? 构建 API(尤其是和 FastAPI 是绝配!)、处理配置文件、数据管道清洗、任何需要严格检查输入数据的地方!