strict=true使basemodel拒绝隐式类型转换,要求输入类型严格匹配字段声明,如{"age": "25"}传给age: int会报validationerror;仅对当前模型生效,不递归影响嵌套模型。

strict=True 会让 BaseModel 拒绝隐式类型转换
默认情况下,Pydantic 会尝试把传入的数据“凑合”转成字段声明的类型,比如把字符串 "42" 转成 int,把 1 转成 bool。开了 strict=True,这种自动转换就停了——类型必须严格匹配。
常见错误现象:ValidationError 报 “Input should be a valid integer, got a string” 这类提示,不是模型写错了,是 strict 模式下你传了 {"age": "25"} 却声明了 age: int。
- 只对单个模型生效:在
BaseModel定义时加model_config = {"strict": True},或实例化时传strict=True - 不递归影响嵌套模型:子模型得自己设
strict,父模型开了没用 - 和
type_checking无关:strict 控制的是输入解析阶段,不是运行时类型检查
strict=False(默认)下哪些转换最常踩坑
默认宽松模式看似省事,但容易掩盖数据质量问题。比如 email: EmailStr 字段接收 "foo@bar"(缺域名后缀)也能过,因为 Pydantic 先转成字符串再校验;又比如 created_at: datetime 接收 "2023-01-01" 会被补全成午夜时间,而你可能期望它直接报错。
-
str → int/float:只要能 parse 就转," 123 "、"+45.6"都行 -
int/float → bool:0变False,非零变True,连1.0都算True -
list → set/tuple:自动去重或打包,但丢失插入顺序或重复项语义 - 自定义
@field_validator在类型转换之后运行,所以 validator 看到的已经是“被转过”的值
什么时候必须开 strict=True
当你的数据源不可信,或需要精确控制输入边界时——比如 API 接收前端 JSON,而前端可能把数字字段错传成字符串;又比如做配置加载,要求 timeout: int 必须是整数字面量,不能是 "30"。
立即学习“Python免费学习笔记(深入)”;
- CI/CD 中验证配置文件:用 strict 避免 YAML 解析器把
123和"123"统一当字符串处理后又悄悄转回 int - 与强类型语言对接(如 Go/TypeScript):它们不会做隐式转换,Python 端开 strict 才对得齐行为
- 调试数据漂移:某个字段突然从 int 变成 str,strict 模式能让问题在入口就暴露,而不是在下游计算时报
TypeError: unsupported operand type(s)
strict mode 对性能和兼容性的影响
开 strict 会略快一点点——少了一轮类型推导和转换逻辑。但真正要注意的是兼容性断层:同一个模型,strict 开关切换后,合法输入集合完全不同,API 行为会突变。
- Pydantic v2 中
strict是 per-model 设置,v1 的Config.strict已废弃,别混用 - 第三方库(如 FastAPI)默认不传
strict,你得在模型里显式写,不然路由 handler 里的模型实例还是宽松的 - 和
validate_assignment=True一起用时,字段赋值也会触发 strict 检查,注意obj.field = "123"在int字段上会直接抛异常
最易被忽略的点:strict 不影响 model_dump() 或 model_json() 输出,只管进不管出;另外,None 值是否允许,取决于字段是否可选(Optional),跟 strict 无关。










