异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置并进行调试。python用异常对象(exception object)来表示异常。遇到错误后会引发异常,如果异常未被处理或捕捉,程序就会用所谓的回溯(traceback)终止执行。
1、raise语句
为了引发异常,可以使用一个类(应该是exception的子类)或者实例参数调用raise语句。使用类时,程序会自动创建类的一个实例。
In [1]: raise Exception
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-1-fca2ab0ca76b> in <module>()
----> 1 raise Exception
Exception:
In [2]: raise ArithmeticError
---------------------------------------------------------------------------
ArithmeticError Traceback (most recent call last)
<ipython-input-2-36d9a98b39c2> in <module>()
----> 1 raise ArithmeticError
ArithmeticError:
2、内建异常类
- Exception : 所有异常的基类
- AttributeError : 特征引用或者复制失败时引发
- IOError : 试图打开不存在文件(包括其他情况)时引发
- IndexError : 在使用序列不存在的索引引发
- Key Error : 在使用映射不存在的键时引发
- NameError : 在找不到名字(变量)时引发
- SyntaxError : 在代码为错误形式时引发
- TypeError : 在内建操作或者函数应用于错误类型的对象时引发
- ValueError : 在内建操作或者函数应用与正确类型的对象,但是该对象使用不合适的值时引发
- ZeroDivisionError : 在除法或者模除操作的第二个参数为0时引发
3、自定义异常类型
- Python中也可以自定义自己的特殊类型的异常,只需要确保从Exception类继承(直接或间接)即可:
class SomeCustomException(Exception):
pass
4、捕捉异常
- Python中使用try/except关键字来捕捉异常
In [1]: try:
...: x = input('enter the 1 num:')
...: y = input('enter the 2 num:')
...: print(int(y)/int(x))
...: except ZeroDivisionError:
...: print('can\'s be zore')
enter the 1 num:0
enter the 2 num:1
can's be zore
5、捕捉多个异常
- 如果需要一个块捕捉多个类型异常,那么可以将他们作为元组输出
In [2]: try:
...: x = input('enter the 1 num:')
...: y = input('enter the 2 num:')
...: type(x)
...: print(int(y)/int(x))
...: except (EOFError,ZeroDivisionError,NameError,TypeError):
...: print('try again')
...:
...:
enter the 1 num:0
enter the 2 num:4
try again
- 如果需要一个块捕捉多个类型异常,那么可以继续使用except Exception
In [3]: try:
...: x = input('enter the 1 num:')
...: y = input('enter the 2 num:')
...: type(x)
...: print(int(y)/int(x))
...: except ZeroDivisionError:
...: print('Zero cant be division')
...: except Exception:
...: print('other Error')
...:
...:
enter the 1 num:0
enter the 2 num:4
Zero cant be division
In [4]: try:
...: x = input('enter the 1 num:')
...: y = input('enter the 2 num:')
...: type(x)
...: print(int(y)/int(x))
...: except ZeroDivisionError:
...: print('Zero cant be division')
...: except Exception:
...: print('other Error')
...:
...:
enter the 1 num:d
enter the 2 num:2
other Error
6、捕获对象
- 记录异常的同时,程序不会中断停止
In [16]: try:
...: print(2/'0') # unsupported operand type(s) for /: 'int' and 'str'
...: except (ZeroDivisionError,Exception) as e:
...: print(e)
unsupported operand type(s) for /: 'int' and 'str'
- 全捕获异常对象,那么使用except中忽略所有的异常类:
In [22]: try:
...: print(2/'0')
...: except:
...: print('xxxx')
...:
xxxx
- 如果没有异常出现,外加使用else语句实现
In [23]: try:
...: print(2/1)
...: except:
...: print('xxxx')
...: else:
...: print('nothing')
...:
2.0
nothing
设定一个输入正确才break退出的程序:
In [26]: while True:
...: try:
...: x = input('enter the 1 num:')
...: y = input('enter the 2 num:')
...: type(x)
...: print(int(y)/int(x))
...: except ZeroDivisionError:
...: print('Zero cant be division')
...: except Exception:
...: print('other Error')
...: else:
...: break
...:
...:
enter the 1 num:0
enter the 2 num:2
Zero cant be division
enter the 1 num:f
enter the 2 num:2
other Error
enter the 1 num:`
enter the 2 num:2
other Error
enter the 1 num:1
enter the 2 num:1
1.0
7、 finally子句
- finally子句和try子句联合使用但是和except语句不同,finally不管try子句内部是否有异常发生,都会执行finally子句内的代码。
- finally常用于关闭文件或者在Socket中。
In [21]: try:
...: print(2/'0')
...: except (ZeroDivisionError,Exception):
...: print('Error occur')
...: finally:
...: print('异常已执行')
...:
Error occur
异常已执行
- finally用于清洗异常
In [27]: x = None
...: try:
...: x = 1/0
...: finally:
...: print('清洗异常')
...: del x
...:
清洗异常
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-27-5a756a1da48a> in <module>()
1 x = None
2 try:
----> 3 x = 1/0
4 finally:
5 print('清洗异常')
ZeroDivisionError: division by zero
In [28]: x
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-28-401b30e3b8b5> in <module>()
----> 1 x
NameError: name 'x' is not defined
or 继续定义 x =10:
In [29]: x = None
...: try:
...: x = 1/0
...: finally:
...: print('清洗异常')
...: x = 10
...:
...:
清洗异常
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-29-671ddcbf51b6> in <module>()
1 x = None
2 try:
----> 3 x = 1/0
4 finally:
5 print('清洗异常')
ZeroDivisionError: division by zero
In [30]: x
Out[30]: 10
将try与except语句结合,得到捕获异常对象,并最终执行finally语句:
In [31]: x = None
...: try:
...: x = 1/0
...: except ZeroDivisionError as e:
...: print(e)
...: finally:
...: print('清洗异常')
...: x = 10
...:
...:
...:
division by zero
清洗异常
In [32]: x
Out[32]: 10