9.1 异常与捕获
异常(exception)是程序运行过程中出现的非正常情况。异常不一定意味着程序必须崩溃;如果提前设计好处理方式,程序可以给出提示、记录问题,或者继续执行后续逻辑。
常见异常
常见异常包括:
ValueError:值不符合要求,例如把"3.6"转成int。ZeroDivisionError:除数为 0。IndexError:列表下标(index)越界。KeyError:字典中不存在这个键(key)。FileNotFoundError:打开不存在的文件。AttributeError:访问不存在的属性(attribute)。
注意
异常不是用来代替普通条件判断的。能用
if 提前判断的简单规则,通常仍然应该先用 if;异常更适合处理“运行时才知道是否会失败”的情况。正在加载概念检查...
try、except、else、finally
try 中放可能出错的代码,except 中放错误处理代码,else 中放没有异常时才执行的代码,finally 中放无论是否出错都要执行的收尾代码。
正在加载交互实验...
python
try:
dividend = int(input("请输入被除数:"))
divisor = int(input("请输入除数:"))
quotient = dividend / divisor
except ValueError:
print("只支持输入整数。")
except ZeroDivisionError:
print("除数不能为 0。")
else:
print("%d / %d = %.2f" % (dividend, divisor, quotient))
finally:
print("本次计算结束。")一次可能的运行结果:
text
请输入被除数:21
请输入除数:4
21 / 4 = 5.25
本次计算结束。else 的好处是把“成功后要做的事”和 try 里的风险代码分开。这样代码读起来更清楚:try 负责尝试,except 负责失败,else 负责成功,finally 负责收尾。
正在加载概念检查...
捕获具体异常
不要一开始就写过宽的 except Exception。如果什么异常都捕获,程序可能把真正的 bug 也吞掉,导致问题更难发现。
python
try:
score = int(input("请输入成绩:"))
except ValueError:
print("成绩必须是整数。")上面只捕获 ValueError,因为这段代码真正预期的失败就是“输入不能转成整数”。
正在加载概念检查...
raise
raise 可以主动抛出异常。它适合表达“这个输入不满足函数要求”,让错误在正确的位置被发现,再交给调用者处理。
正在加载交互实验...
python
def normalize_score(score):
if score < 0 or score > 100:
raise ValueError("成绩必须在 0 到 100 之间。")
return score / 100
try:
score = int(input("请输入成绩:"))
ratio = normalize_score(score)
except ValueError as error:
print("输入无效:%s" % error)
else:
print("成绩比例:%.2f" % ratio)一次可能的运行结果:
text
请输入成绩:120
输入无效:成绩必须在 0 到 100 之间。这里 normalize_score() 不负责打印提示,它只负责保证自己的输入合法。外层调用者负责决定怎么提示用户。
正在加载概念检查...
正在加载本节练习...