纸上得来终觉浅,绝知此事要躬行。
写程序的时候,经常会写出一些低级错误的代码,则会导致错误和异常的出现,而如何快速定位问题所在就是其中最为重要的事情了。
- 错误:通常指的是程序运行中不可恢复的问题
- 异常:通常指的是可以在程序运行时恢复的错误
1. 语法格式
- 常见组合方式
In [1]: try:
...: pass
...: except ZeroDivisionError as e:
...: pass
...: except (IndexError, ValueError) as e:
...: pass
...: else:
...: pass
...: finally:
...: pass
...:
- 实例展示说明
In [2]: def div(a, b):
...: try:
...: result = a / b
...: except ZeroDivisionError as e:
...: print(e)
...: else:
...: print(f'result is {result}')
...: finally:
...: print(f'finally')
...:
In [3]: div(2, 1)
result is 2.0
finally
In [4]: div(2, 0)
division by zero
finally
# 使用except而不带任何异常类型可以捕获所有异常
# 不推荐使用,因为不方便排查,只会给自己挖坑而已
In [5]: try:
...: div(1, 0)
...: except:
...: print('Error')
...:
Error
2. 抛出异常
- 使用
raise
关键字,可以抛出异常
In [6]: def fn(i):
...: if i<0:
...: raise Exception('i<0')
...:
- 未处理异常会向顶层抛出,直到最顶层
In [7]: def fn():
...: 3/0
...: def main():
...: fn()
...: main()
...:
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-7-9b0c900d13ec> in <module>()
3 def main():
4 fn()
----> 5 main()
6
<ipython-input-7-9b0c900d13ec> in main()
2 3/0
3 def main():
----> 4 fn()
5 main()
6
<ipython-input-7-9b0c900d13ec> in fn()
1 def fn():
----> 2 3/0
3 def main():
4 fn()
5 main()
ZeroDivisionError: integer division or modulo by zero
3. 异常继承
- BaseException
- Exception ==> 通常的异常处理
- GeneratorExit ==> 生成器抛出的异常
- KeyboardInterrupt ==> 中断
- SystemExit ==> 系统退出异常
- 一种下面三个为特殊的异常,而
Exception
是除这个三个以外的异常都是继承自它的。
# 生成器异常
In [8]: def gen():
...: c = 0
...: while True:
...: yield 'Hello'
...: c += 1
...: if c > 3:
...: raise GeneratorExit()
...: for x in gen():
...: print(x)
...:
Hello
Hello
Hello
Hello
---------------------------------------------------------------------------
GeneratorExit Traceback (most recent call last)
<ipython-input-8-72495e11777b> in <module>()
6 if c > 3:
7 raise GeneratorExit()
----> 8 for x in gen():
9 print(x)
10
<ipython-input-8-72495e11777b> in gen()
5 c += 1
6 if c > 3:
----> 7 raise GeneratorExit()
8 for x in gen():
9 print(x)
GeneratorExit:
# 硬件中断
In [10]: try:
...: while True:
...: print('Hello')
...: except KeyboardInterrupt:
...: print('exit...')
Hello
Hello
Hello^Cexit...
4. 自定义异常
当一个类继承自
Exception
及其派生类的时候,就是一个自定义异常。
- 内置异常多以 Error 结尾
In [11]: class MyException(Exception):
....: pass
....:
In [12]: raise MyException('MyException')
---------------------------------------------------------------------------
MyException Traceback (most recent call last)
<ipython-input-12-904b3e049f76> in <module>()
----> 1 raise MyException('MyException')
MyException: MyException
In [13]: try:
....: raise MyException('123')
....: except MyException as e:
....: print(e)
....:
123
- 自定义异常建议
- 以
Exception
后缀表示可修复异常 - 以
Error
后缀表示不可修复异常
- 以
class RequestException(Exception):
pass
classRequestError(Exception):
pass