>>> from env_helper import info; info()
页面更新时间: 2020-03-28 16:11:39
操作系统/OS: Linux-4.19.0-8-amd64-x86_64-with-debian-10.3 ;Python: 3.7.3

7.1. Python异常处理

7.1.1. 什么是异常?

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。

Python使用异常对象来表示异常状态,并在遇到错误时引发异常。异常对象未被处理(或捕获)时,程序将终止并显示一条错误消息(traceback)。

>>> 1 / 0
---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

<ipython-input-1-bc757c3fda29> in <module>()
----> 1 1 / 0


ZeroDivisionError: division by zero

如果异常只能用来显示错误消息,就没多大意思了。但事实上,每个异常都是某个类(这里 是ZeroDivisionError)的实例。你能以各种方式引发和捕获这些实例,从而逮住错误并采取措施, 而不是放任整个程序失败。

正如你看到的,程序出现问题时,将自动引发异常。先来看看如何自主地引发异常,还有如何创建异常,然后再学习如何处理这些异常。

7.1.2. raise 语句

要引发异常,可使用raise语句,并将一个类(必须是Exception的子类)或实例作为参数。 将类作为参数时,将自动创建一个实例。下面的示例使用的是内置异常类Exception:

>>> raise Exception
---------------------------------------------------------------------------

Exception                                 Traceback (most recent call last)

<ipython-input-1-2aee0157c87b> in <module>
----> 1 raise Exception


Exception:
>>> raise Exception('hyperdrive overload')
---------------------------------------------------------------------------

Exception                                 Traceback (most recent call last)

<ipython-input-2-069f4daa368b> in <module>
----> 1 raise Exception('hyperdrive overload')


Exception: hyperdrive overload

在第一个示例(raise Exception)中,引发的是通用异常,没有指出出现了什么错误。在第二个示例中,添加了错误消息hyperdrive overload。

有很多内置的异常类,下面描述了最重要的几个。这些异常类都可用于 raise 语句中。

  • Exception | 几乎所有的异常类都是从它派生而来的

  • AttributeError | 引用属性或给它赋值失败时引发

  • OSError | 操作系统不能执行指定的任务(如打开文件)时引发,有多个子类

  • IndexError | 使用序列中不存在的索引时引发,为LookupError的子类 8

  • KeyError | 使用映射中不存在的键时引发,为LookupError的子类

  • NameError | 找不到名称(变量)时引发

  • SyntaxError | 代码不正确时引发

  • TypeError | 将内置操作或函数用于类型不正确的对象时引发

  • ValueError | 将内置操作或函数用于这样的对象时引发:其类型正确但包含的值不合适

  • ZeroDivisionError | 在除法或求模运算的第二个参数为零时引发

7.1.3. 自定义的异常类

虽然内置异常涉及的范围很广,能够满足很多需求,但有时你可能想自己创建异常类。例如, 在前面的超光速推进装置过载(hyperdrive overload)示例中,使用专用的HyperdriveError类来 表示超光速推进装置的错误状态不是更自然吗?好像提供了错误消息就足够了,但在8.3节你将看到,可基于异常所属的类选择性地处理异常。因此,如果你要使用特殊的错误处理代码对超光 速推进装置错误进行处理,就必须有一个专门用于表示这些异常的类。

那么如何创建异常类呢?就像创建其他类一样,但务必直接或间接地继承Exception(这意 味着从任何内置异常类派生都可以)。因此,自定义异常类的代码类似于下面这样:

>>> class SomeCustomException(Exception): pass

工作量真的不大。(当然,如果你愿意,也可在自定义异常类中添加方法。)