Pydantic 健壮性源于精准约束而非冗余代码:类型与业务语义需对齐,Optional[str] + Field(default=None) 表达可选字段,Field(...) 表示必填;嵌套校验错误需查 loc 和 input;exclude_unset 排除未传字段,exclude_defaults 排除默认值字段;自定义 eq 或 hash 时须设 frozen=True。

Pydantic 的核心健壮性不来自“写得多”,而来自“约束得准”——类型声明 + 验证逻辑必须对齐业务语义,否则 ValidationError 会早暴露但你未必能读懂它在拒什么。
用 BaseModel 替代 dataclass 时,必须显式处理可选字段和默认值
很多人直接把 @dataclass 改成继承 BaseModel,结果发现 None 字段没报错、空字符串被放过、缺失字段没提示——因为 Pydantic 默认允许 None 赋给非可选字段(只要类型标注没写 Optional),且 default=None 不等于“该字段可缺”。
- 要表达“字段可选且无默认值”,必须用
Optional[str]+Field(default=None)或更推荐的Field(default=None, default_factory=dict) - 要表达“字段必填”,就只写
name: str,别加default=None,否则 Pydantic 会把它当“有默认值”,从而跳过缺失检查 -
Field(default=...)中的...是Ellipsis,表示“无默认值但必填”,不是省略号字符
嵌套模型校验失败时,ValidationError 的 errors() 输出结构容易误读
错误信息是嵌套字典列表,loc 字段表示路径,但它的值是元组(如 ('user', 'profile', 'age')),不是点分字符串;msg 里常出现 “Input should be a valid integer” 这类泛化描述,实际原因可能是字符串带空格、或传了 None 给非可选 int 字段。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 调试时优先打印
exc.errors()[0]['loc']和exc.errors()[0]['input'],比只看msg更快定位原始输入值 - 对嵌套结构,建议在父模型中用
validate_assignment=True并配合@field_validator做跨字段约束,而不是依赖子模型单独验证 - 避免在
__init__中手动调用model_validate——Pydantic v2 已默认启用,重复调用会触发两次验证
model_dump() 和 model_dump_json() 的 exclude_unset 与 exclude_defaults 行为差异极大
这两个参数控制序列化输出内容,但含义常被混淆:exclude_unset 排除的是“初始化时根本没传的字段”,exclude_defaults 排除的是“值等于字段默认值的字段”——哪怕你显式传了默认值,它仍会被排除。
- API 返回 DTO 时,用
exclude_unset=True可确保只返回客户端真正设置过的字段(适合 PATCH 场景) - 日志记录或调试时,用
exclude_defaults=False(默认)才能看到所有字段当前值,包括未显式设置但已由默认工厂生成的字典/列表 -
model_dump(mode='json')比model_dump_json()更灵活,支持round_trip=True处理datetime等类型往返,且可统一控制by_alias和exclude_none
最常被忽略的点:Pydantic 的健壮性高度依赖你是否重写了 __eq__ 或 __hash__。一旦自定义,必须同步处理 model_config = ConfigDict(frozen=True),否则实例可能在字典键或集合中行为异常——而这个异常不会在模型构建时抛出,只会在运行时数据结构操作中静默失效。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










