异常通常是Python脚本在运行过程中引发的错误。如果在脚本中未包含对相关异常进行处理的代码,那么脚本将会由于异常而终止运行。在Python中,可以为脚本添加异常处理代码,以应对可能出现的错误,从而使脚本更健壮。
7.1 异常的处理
在脚本运行程序中,常见的异常有除零、下标越界等。在Python中,当这些异常产生时,可以捕获这些异常,并编写相关的处理语句,使脚本不会以外中断。
7.1.1 使用try语句捕获异常
在Python中,可以使用try语句来捕获异常。和Python中的其他语句一样,try语句也要使用缩进结构。try语句有一个可选的else语句块。一般的try语句形式如下:
try:
<语句> #要捕获异常的语句
except <异常名1>: #要进行处理的异常
<语句> #要异常进行处理的语句
except <异常名2>: #要进行处理的异常
<语句> #对异常进行处理的语句
else:
<语句> #如果异常未被触发,则执行该语句
try语句的执行流程如下图所示:
try语句还有一种不包含except和else语句的特殊形式,如下:
try:
<语句>
finally:
<语句>
不管try语句块中是否发生异常,都执行finally语句块。下面是使用try语句捕获异常的代码示例:
7.1.2 常见异常的处理
在except语句中可以捕获指定的异常,除此之外,except语句还可以产生异常时的附加数据。python中常用的内置异常如下表7-1所示。
except语句主要有以下几种用法:
except: #捕获所有异常
except <异常名>: #捕获指定异常
except (异常名1,异常名2):#捕获异常名1或异常名2
except <异常名> as <数据>: #捕获指定异常及附加的数据
except (异常名1,异常名2) as <数据>: #捕获异常名1或异常名2及异常的附加数据
以下代码使用except语句捕获异常。
7.1.3 多重异常的捕获
在Python中,可以在try语句中嵌套另一个try语句。由于Python将try语句放在堆栈中,因此,一旦引发异常,Python将匹配最近的except语句。如果except语句能够处理该异常,则外围的try语句将不会捕获异常;如果except语句忽略该异常,则异常将被外围的try语句捕获。
下面的代码在try语句中嵌套另一个try语句。
l = [1,2] #定义一个列表
try: #嵌套try语句
try:
print(l[5])
except: #捕获所有异常
print('Error1')#打印‘Error1’
except: #捕获所有异常
print('Error2')
else:
print('No Error')
Error1 #此处为内嵌try语句输出
No Error #此处为外围try语句输出,表示try语句中未引发异常
try:
try:
print(l[1]/0)
except IndexError: #仅捕获IndexError异常
print('Errorl')
except:
print('Error2')
else:
print('No Error')
Error2 #异常被外围try语句捕获
7.2 用代码引发异常
除Python内置的异常外,在脚本中还可以使用raise语句手动引发异常。在类中也可以使用raise语句引发异常,并向异常传递数据。
使用raise语句可以定义新的异常类型,以适应脚本的需要。例如,对用户输入数据的长度有要求,则可以使用raise语句引发异常,以确保数据输入的长度符合要求。
7.2.1 使用raise语句引发异常
使用raise语句引发异常十分简单。raise语句的一般形式如下:
raise 异常名
raise 异常名,附加数据
raise 类名
下面的代码使用try语句捕获由raise语句引发的异常。
7.2.2 assert-简化的raise语句
在python中,使用assert语句同样可以引发异常。但与raise语句不同,assert语句只有在条件测试为假时才引发异常。 assert语句的一般形式如下:
assert <条件测试>,<异常附加数据> #异常附加数据是可选的
从上述代码中可以看出,assert语句相当于raise语句和if语句联合使用。例如下面的assert语句:
assert len(l)
if len(l):
raise AssertionError,<附加数据>
需要注意的是,assert语句一般用于开发时对程序条件的验证,只有当内置_debug_为True时,assert语句才有效。当Python的脚本通过-O选项编译成字节码文件时,assert语句将被移除。
7.2.3 自定义异常类
在Python中,可以通过继承Exception类来创建自己的异常类。异常类和其他的类并没有区别,一般在异常类中仅需要定义几个属性信息。
下面的代码通过继承Exception类来生成一个MyError类
引用说明
《Python数据分析从入门到精通》 张啸宇 李静 编著