>>> 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的子类 8KeyError
| 使用映射中不存在的键时引发,为LookupError的子类NameError
| 找不到名称(变量)时引发SyntaxError
| 代码不正确时引发TypeError
| 将内置操作或函数用于类型不正确的对象时引发ValueError
| 将内置操作或函数用于这样的对象时引发:其类型正确但包含的值不合适ZeroDivisionError
| 在除法或求模运算的第二个参数为零时引发
7.1.3. 自定义的异常类¶
虽然内置异常涉及的范围很广,能够满足很多需求,但有时你可能想自己创建异常类。例如, 在前面的超光速推进装置过载(hyperdrive overload)示例中,使用专用的HyperdriveError类来 表示超光速推进装置的错误状态不是更自然吗?好像提供了错误消息就足够了,但在8.3节你将看到,可基于异常所属的类选择性地处理异常。因此,如果你要使用特殊的错误处理代码对超光 速推进装置错误进行处理,就必须有一个专门用于表示这些异常的类。
那么如何创建异常类呢?就像创建其他类一样,但务必直接或间接地继承Exception(这意 味着从任何内置异常类派生都可以)。因此,自定义异常类的代码类似于下面这样:
>>> class SomeCustomException(Exception): pass
工作量真的不大。(当然,如果你愿意,也可在自定义异常类中添加方法。)