Python数据校验核心是早发现、早报错、有提示,在关键入口用类型注解+runtime检查(如isinstance)校验参数,结合自定义异常、避免默认值掩盖问题,并禁用assert用于生产环境。

Python数据校验的核心不是堆砌装饰器或引入重型框架,而是用最直接的方式在关键入口处识别非法输入,并给出明确反馈。重点在于“早发现、早报错、有提示”,而不是等程序跑一半才崩溃。
用类型注解 + runtime 检查守住参数入口
类型注解本身不运行检查,但配合 isinstance() 或第三方库(如 typeguard)可实现轻量级校验。推荐在函数开头手动加一层判断,逻辑清晰、调试友好:
- 对必填参数,先检查是否为
None,再检查类型 - 对数值类参数(如
int,float),额外验证范围(如不能为负、不能超限) - 对字符串,检查是否为空、长度是否合规、是否含非法字符
- 对容器类(
list,dict),确认非空、元素类型一致、键名存在且合法
自定义异常比 ValueError 更易定位问题
不要只抛 raise ValueError("参数错了")。定义专属异常类,能快速区分是用户输入问题、配置错误还是内部逻辑异常:
- 继承
Exception,命名体现场景,例如InvalidEmailError、OutOfRangeError - 异常信息包含具体参数名、实际值、期望条件,例如:
"age must be between 0 and 150, got: -5" - 在日志或 API 响应中捕获时,可根据异常类型做差异化处理(如返回 400 还是 500)
避免“校验黑洞”:别让 None / 空字符串/默认值悄悄溜过
很多 bug 来自默认值掩盖了原始问题。例如函数定义 def process(name=""):,调用时传了空字符串却没报错,后续操作可能出错但堆栈指向下游而非源头:
立即学习“Python免费学习笔记(深入)”;
- 显式区分“未传参”和“传了空值”,可用
sentinel = object()作默认占位符 - 对字符串参数,用
if not name.strip():而非if not name:,避免空格干扰判断 - 对字典参数,用
.get(key, default)获取值后,仍需校验该 default 是否符合业务要求
简单场景优先用 assert,但仅限开发阶段
assert 适合快速验证不变量或调试假设,比如“这个列表处理前必须非空”。但它在 python -O 模式下会被忽略,**不能用于生产环境的数据防护**:
- 开发时写
assert isinstance(data, dict), "data must be dict"快速暴露问题 - 上线前务必替换成显式
if not isinstance(...): raise ... - 不要用
assert校验用户输入、文件内容、网络响应等不可控数据
不复杂但容易忽略——校验的本质是把模糊的“可能出错”变成明确的“这里必须满足什么”,让错误发生在离源头最近的地方。










