输入边界检查是提前拦截非法输入以保障程序稳定安全的关键习惯,需用isinstance()检查类型并验证数值范围,明确函数输入契约。

Python 输入边界检查的核心,是提前拦截非法或意外输入,避免程序在后续逻辑中崩溃或产生错误结果。它不是“多此一举”,而是让函数更可预测、更易调试、更安全的关键习惯。
明确输入契约,用类型与范围双重约束
函数应清楚声明它能接受什么。比如一个计算折扣后价格的函数,不能只假设传进来的是数字——用户可能输字符串"100"、负数、None,甚至列表。
建议做法:
- 用 isinstance() 检查基础类型(如
int、float、str),比直接type(x) == int更灵活(支持继承) - 对数值型参数,立即验证上下界,例如:
if not (0 - 对字符串,检查是否为空、长度是否超限、是否含非法字符(如路径名中禁止
../)
把校验逻辑封装成独立函数或装饰器
重复写 if not isinstance(...) 很容易遗漏或不一致。把通用检查抽出来,既提升复用性,也让主逻辑更干净。
立即学习“Python免费学习笔记(深入)”;
例如定义一个轻量装饰器:
def require_positive(name):
def decorator(func):
def wrapper(*args, **kwargs):
# 假设第一个位置参数是待检查值
if args and args[0] <= 0:
raise ValueError(f"{name} must be positive")
return func(*args, **kwargs)
return wrapper
return decorator
<p>@require_positive("count")
def fetch_items(count):
return ["item"] * count
也可用 pydantic 或 dataclasses + __post_init__ 实现更结构化的输入建模。
区分错误类型,给出具体提示
不要统一抛 Exception 或模糊的 ValueError。不同问题应有不同异常和清晰信息,方便调用方捕获处理,也利于日志排查。
常见分类建议:
- TypeError:类型完全不符(如传了 list 给期望 int 的参数)
- ValueError:类型正确但值非法(如 int 是 -5,但要求 ≥ 0)
-
KeyError:字典键缺失且不可默认(区别于用
.get()安全访问) - 自定义异常类(如
InvalidRangeError)适合复杂业务规则
错误消息里带上实际值和预期范围,例如:f"Expected age in [0, 150], got {age}"。
外部输入必须默认校验,内部调用可酌情跳过
从用户输入(input()、命令行 sys.argv、Web 请求 body)、文件读取、数据库查询结果等来源的数据,一律视为不可信,必须校验。
而模块内函数间调用,若已由上层保证输入合法,可省略重复检查——但需在文档或类型注解中明确说明前提,例如:
def _compute_tax(amount: float) -> float:
"""Assumes amount >= 0. Caller must validate."""
return amount * 0.08
配合 typing 注解 + mypy 静态检查,能进一步把部分边界问题挡在运行前。










