Python入门篇之异常处理

83 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

🔥 本文由 程序喵正在路上原创,在稀土掘金首发!
💖 系列专栏:Python筑基
🌠 首发时间:2022年9月13日
🦋 欢迎关注🖱点赞👍收藏🌟留言🐾
🌟 一以贯之的努力 不得懈怠的人生

异常处理:try-except 语句

观察下面这段小程序:

num = eval(input("请输入一个整数:"))
print(num**2)

正常输入的运行结果如下:

请输入一个整数:100
10000

当用户输入数字时,程序正常执行,如果用户输入的不是数字呢?

异常输入的运行结果如下:

请输入一个整数:abc  
Traceback (most recent call last):  
  File "D:\pythonProject\venv\test.py", line 1, in <module>  
    num = eval(input("请输入一个整数:"))  
  File "<string>", line 1, in <module>  
NameError: name 'abc' is not defined. Did you mean: 'abs'?  

可以看到,Python 解释器返回了异常信息,同时退出程序,下图具体说明了这个异常信息中各部分的含义

image.png

Python 异常信息中最重要的部分是异常类型,它表明发生异常的原因,也是程序处理异常的依据

Python 使用 try-except 语句实现异常处理,其基本语法格式如下:

try:
    <语句块 1>
except <异常类型>:
    <语句块 2>

语句块 1 是正常执行的程序内容,当发生异常时执行 except 保留字后面的语句块,为上述小程序增加异常处理,代码如下:

try:
    num = eval(input("请输入一个整数:"))
    print(num**2)
except NameError:
    print("输入错误,请输入一个整数!")

此时异常输入的运行结果如下:

请输入一个整数:abc
输入错误,请输入一个整数!

异常和错误

在编程语言中,异常和错误是两个相似但不同的概念

异常和错误都可能引起程序执行错误而退出,它们属于程序没有考虑到的例外情况( exception )。然而,绝大多数不可控因素是可以预见的,例如,程序期望获得数字输入却得到了其他字符输入、打开一个不存在的文件等。这种可以预见的例外情况称为“异常”( checked exception ),异常发生后经过妥善处理可以继续执行

另外一些因为程序编码逻辑产生的不可预见的例外情况称为“错误”( unchecked exception),错误发生后程序无法恢复执行,而且程序本不该处理这类可能的例外,例如,对于一个包含 5 个字符的字符串,程序去索引其中第 6 个元素,这种错误完全可以避免

异常的高级用法

除了最基本的 try-except 用法,Python 异常还有一些略微高级的用法,这些方法在实际程序设计中也十分常用

try-except 语句可以支持多个 except 语句,语法格式如下:

try:
    <语句块 1>
except <异常类型 1>:
    <语句块 2>
...
except <异常类型 N>:
    <语句块 N+1>
except:
    <语句块 N+2>

其中,第 1 到第 Nexcept 语句后面都指定了异常类型,说明这些 except 所包含的语句块只处理这些类型的异常。最后一个 except 语句没有指定任何类型, 表示它对应的语句块可以处理所有其他异常。这个过程与 if-elif-else 语句类似,是分支结构的一种表达方式,例如如下代码:

try:
    alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    index = eval(input("请输入一个整数:"))
    print(alp[index])
except NameError:
    print("输入错误,请输入一个整数!")
except:
    print("其他错误")

该程序将用户输入的数字作为索引从字符串 alp 中返回一个字符,当用户输入非整数字符时,except NameError 异常被捕获到,提示用户输入类型错误,当用户输入数字不在 025 之间时,异常被 except 捕获,程序打印其他错误信息,执行过程和结果如下:

请输入一个整数:abc
输入错误,请输入一个整数!

请输入一个整数:100
其他错误

除了 tryexcept 保留字外,异常语句还可以与 elsefinally 保留字配合使用,语法格式如下:

try:
    <语句块 1>
except <异常类型>:
    <语句块 2>
else:
    <语句块 3>
finally:
    <语句块 4>

此处的 else 语句与 for 循环和 while 循环中的 else 一样,当 try 中的语句块 1 正常执行结束且没有发生异常时,else 中的语句块 3 执行,可以看作是对 try 语句块正常执行后的一种追加处理。finally 语句块则不同,无论 try 中的语句块 1 是否发生异常,语句块 4 都会执行,可以将程序执行语句块 1 的一些收尾工作放在这里,例如,关闭、打开文件等

采用 elsefinally 修改代码如下:

try:
    alp = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    index = eval(input("请输入一个整数:"))
    print(alp[index])
except NameError:
    print("输入错误,请输入一个整数!")
else:
    print("没有发生异常")
finally:
    print("程序执行完毕,不知道是否发生了异常")

程序的测试结果如下:

请输入一个整数:5
F
没有发生异常
程序执行完毕,不知道是否发生了异常

请输入一个整数:abc
输入错误,请输入一个整数!
程序执行完毕,不知道是否发生了异常

Python 能识别多种异常类型,但不建议读者编写程序时过度依赖 try-except 这种异常处理机制。try-except 异常一般只用来检测极少发生的情况, 例如,用户输入的合规性或文件打开是否成功等。对于前面例子中索引字符串超过范围的情况应该尽量在程序中采用if语句直接判断,而避免通过异常处理来应对这种可能发生的 “错误”

对于面向商业应用的软件产品,稳定性和可靠性是最重要的衡量指标之一。即使这类软件产品也不会滥用 try-except 类型语句。因为采用 try-except 语句会影响代码的可读性,增加代码维护难度,因此,一般只在关键地方采用 try-except 类型语句处理可能发生的异常。建议读者结合函数设计统筹应用异常处理。更多经验还需要实践来积累

看到最后,可能会有小伙伴想问:“ 到底什么时候该使用异常语句呢? ”

对于异常语句,程序员都是对它又爱又恨,其实,想用就用吧,用户体验好才是王道!