在程序运行的过程中,难免会遇到未知错误(Error或Exception)。例如,某次计算使得变量x变为0,而x在后续计算中会作为除数参与运算,这就会导致程序出错。通常,Python程序一旦遇到错误即结束,后续计算直接终止。很多时候我们并不想这样,依然希望程序能跳过错误继续执行,这时候就需要用到异常处理。
一、异常类型
异常即一个事件,其会在程序执行过程中发生,影响程序的正常执行。通常,在Python无法正常处理程序时就会发生异常。异常是Python对象,表示一个错误。常见的异常包括:
异常类型 | 说明 |
Exception | 常规错误的基类 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 |
AttributeError | 对象没有这个属性 |
IOError | 输入/输出失败 |
ImportError | 导入模块/对象失败,通常是没安装此模块或名称写错 |
IndexError | 序列中没有此索引,例如索引大于序列长度 |
NameError | 未声明/初始化对象 |
SyntaxError | Python语法错误,如编写不符合语法规范 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数,如调用函数时传入未知参数 |
UnicodeError | Unicode相关错误,如打开文件时使用错误编码格式 |
二、异常处理
可以使用“try/except”语句来捕捉程序中的错误,如下即为该语句的语法格式:
try:codes may raise an exceptionexcept Error1:codes for meeting error1except Error2, Error3:codes for meeting error2else:codes for nothing wrong
(1)异常处理逻辑
try/except语句的执行逻辑是:
执行try内语句,如果遇到异常,就按照异常类型去匹配except语句,并执行该except内的操作;
except语句可以有多条,每条后面可以用逗号分隔多种异常类型;
若except不固定某个异常类型,可以写为“except”或“except Exception”或“except Exception as e”,用于捕获所有类型的异常;
如果没有匹配的except,则当前异常会向当前try的上层try逐层传递直至程序最顶层,若上层try语句没有匹配的except,则程序出错终止,输出错误信息;
当try中语句执行时没有异常,如果有else则先执行其中的语句,然后整个try语句结束。
除此之外,try还可以添加finally语句,无论try中是否有异常,都会在最后执行finally中的语句,例如:
try:print(int("xyz"))except ValueError:print("ValueError")finally:print("finally")# Output:# ValueError# finally
(2)异常抛出
某些情况下,尽管程序逻辑没有错误,但是功能逻辑不符合,此时我们也可以使用raise语句手动抛出异常,其格式为:
raise ExceptionType("Error messages/arguments tuple")例如,计算除法时,除数为1不符合功能逻辑:
def divide(x, y):if y == 1:raise ValueError("y == 1", "wrong")return x / ytry:print(divide(1, 1))except Exception as e:print(e)# Output: ('y == 1', 'wrong')
除此外,也可以使用assert(断言)语句,其先判断某个条件是否成立,若不成立,则抛出异常及参数(参数可以是字符串、异常或没有)。此时,上例变为:
def divide(x, y):assert y != 1, ValueError("y can not be 1")return x / ytry:print(divide(1, 1))except Exception as e:print(e)# Output: ('y == 1', 'wrong')
(3)自定义异常
前面我们提到,异常也是一种Python对象,说明其有对应的数据类。因此我们可以继承异常基类或者某个异常类的方式,自定义新的异常类型。由于这涉及到类的声明和继承等内容,此处就不展开说明。
往期回顾:
零前端高颜值可视化图表交互,PyEcharts攻略|Part.3