在我们的程序开发过程中,需要区分正常过程与异常(非正常)的情况。为了能够处理异常事件,c语言编程中要求使用条件语句进行判断,尤其是我们每调用一个函数,都需要对其返回值进行检查,这样子就会导致我们的代码很大一部分都是对异常的处理,导致代码比较难阅读。在Python中,提供了异常对象来作为解决方案。
1. exception object
Python用异常对象(exception object)来表示异常情况。如果异常对象未被处理或捕捉,程序就会用所谓的回溯(Traceback)终止执行:
def div_func(a, b):
return (a / b)
val = div_func(1, 0)
>>>
Traceback (most recent call last):
File "E:/code_practice/python_exercise/exception_demo.py", line 4, in <module>
val = div_func(1, 0)
File "E:/code_practice/python_exercise/exception_demo.py", line 2, in div_func
return (a / b)
ZeroDivisionError: division by zero
从上面的例子可以看出,由于除数为0,导致ZeroDivisionError异常。我们可以通过对ZeroDivisionError的捕获,避免程序的终止;
try:
val = div_func(1, 0)
print(val)
except ZeroDivisionError:
print('division by zero')
>>>
division by zero
2.常见的exception object
1)Exception: 所有异常的基类,可以表示任意类型的异常
2)AttributeError: 特性引用或赋值失败是引发
3)IOError: 打开不存在的文件或者读写文件失败时引发
4)IndexError: 使用序列中不存在的索引时引发
5)KeyError: 使用Dict中不存在的key时引发
6)NameError: 找不到变量时引发
7)SyntaxError: 代码为错误形式时引发
8)TypeError: 函数应用于错误类型的对象时引发
9)ValueError: 对象赋值为不合适的值时引发
10)ZeroDivisionError: 除0操作时引发
3. 异常的捕获
使用过面向对象的编程语言,如c++, Java等,都是通过try...catch来对异常进行捕获的,那么在Python中也是如此。大致的语法如下:
try:
#statement
...
except exception1:
#handle type of exception1
...
except exception2:
#handle type of exception2
...
except:
#handle any type of exception
...
else:
#when no exception occures, excute here
...
finally:
#whether exception occures or not, it will excute here
...
如果在执行statement代码的过程中,接收到了异常,此时会终止statement的继续执行,跳转到异常的捕获处理情况,依次判断每一个except分支,直到有符合的except object,则会执行对应的异常处理分支,如果都没有符合的分支,则会跳转到执行finally去执行,并且将此异常继续传递给调用者。如果statement代码没有发生异常,则会执行else分支的代码,最后执行finally中的代码。
如果异常没有被捕获处理,则会一直向上层传播,直至有代码对其捕获处理。如果直到最上层都没有捕获处理,则会打印Traceback信息,并终止程序的运行。
大致的处理流程如下:
try->异常->except->finally
try->无异常->else->finally
#未对引发的异常进行捕获处理的情况
list1 = ['a', 'b']
try:
print(list1[3])
except KeyError:
print('handle KeyError')
>>>
Traceback (most recent call last):
File "E:/code_practice/python_exercise/exception_demo.py", line 13, in <module>
print(list1[3])
IndexError: list index out of range
上面引发的是IndexError异常,没有匹配的异常类型,导致异常没有被匹配到。
#使用finally语句
list1 = ['a', 'b']
try:
print(list1[3])
except IndexError:
print('index out of range')
except:
print('catch exception')
finally:
print('exceute finally statement')
>>>
index out of range
exceute finally statement
执行流程: try-->except IndexError-->finally
3.throw exception
在Python中,通过raise来向上抛出一个exception
def change_list(list_arg):
try:
list_arg[len(list_arg)] = 'end'
except IndexError:
print('raise IndexError')
raise IndexError
else:
print('no exception')
finally:
print('exit change_list')
change_list(list1)
>>>
Traceback (most recent call last):
File "E:/code_practice/python_exercise/exception_demo.py", line 24, in change_list
list_arg[len(list_arg)] = 'end'
IndexError: list assignment index out of range
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:/code_practice/python_exercise/exception_demo.py", line 33, in <module>
change_list(list1)
File "E:/code_practice/python_exercise/exception_demo.py", line 27, in change_list
raise IndexError
IndexError