跳到主要内容

错误和异常

八、错误和异常

8.1 句法错误

8.2 异常

异常分为两种

  • 内置异常
  • 用户自定义异常

8.3 异常的处理

  1. 异常的处理就是利用try... except...语句来实现的
while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
  1. except语句可以用元组来指定多个异常
  2. except语句异常匹配可以匹配到自身或其基类,不能与派生类匹配
  3. except语句发生的时候,会自动生成一个对应的异常实例,可以用as重命名
  4. except语句发生的时候,会有相应的值,这些值与异常类型相关。用type()函数和.args参数可以看
  5. Exception类是BaseException的子类,也是很多具体内置异常的基类,不是Exception的派生类的异常往往是不可处理的,它们的出现说明程序就应该终止了。
  6. try...except语句具有可选的else子句,该子句如果存在,它必须放在所有 except 子句之后。 它适用于try子句没有引发异常但又必须要执行的代码。

8.4 触发异常

  1. raise exception可以主动触发异常
  2. 传给raise的异常可以是异常实例,也可以是异常类,若传递的是异常类,会自动调用异常类的构造函数隐式地生成异常实例

8.5 异常链

[8.6 用户自定义异常]

  1. 用户自定义的异常应该也是Exception的派生类
  2. 异常类可以和其他类一样定义很复杂的内容,但通常应该保持简单
  3. 大多数异常命名都以 “Error” 结尾,类似标准异常的命名

8.7 定义清理操作

  1. try还有一个子句finally,用于定义在所有情况下都必须要执行的清理操作。
  2. 不论 try 语句是否触发异常,都会执行 finally 子句,有几种较为复杂的触发异常情况
  3. 在实际应用程序中,finally 子句对于释放外部资源(例如文件或者网络连接)非常有用,无论是否成功使用资源。

8.8 预定义的清理操作

  1. 某些对象定义了不需要该对象时要执行的标准清理操作。无论使用该对象的操作是否成功,都会执行清理操作。这种已经定义好的清理操作就是预定义的清理操作。例如文件对象,可以用with语句

8.9 提出和处理多个无关的异常

  1. 应用场景是:多个任务并行失败,产生多个异常
  2. 可以用内置的ExceptionGroup来包含一个异常的列表,ExceptionGroup本身也是一个异常类,可以用异常信息和异常列表来初始化实例
excs = [OSError('error 1'), SystemError('error 2')]
raise ExceptionGroup('there were problems', excs)
  1. ExceptionGroup的异常列表中可以包含ExceptionGroup实例,这样就实现了异常的嵌套

8.9 丰富异常的文本信息

一个异常初始化的时候往往会伴随着一些信息,如果后面想要添加信息,可以用add_note(note)方法来实现。

try:
raise TypeError("bad type")
except Exception as e:
e.add_note("Add some information")
raise