Python错误和异常


纸上得来终觉浅,绝知此事要躬行。

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

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录