Python错误和异常
纸上得来终觉浅,绝知此事要躬行。
写程序的时候,经常会写出一些低级错误的代码,则会导致错误和异常的出现,而如何快速定位问题所在就是其中最为重要的事情了。
- 错误:通常指的是程序运行中不可恢复的问题
- 异常:通常指的是可以在程序运行时恢复的错误
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