10.1 异常处理

10.1.1 异常

即使语句或表达式在语法上是正确的,但在尝试执行时,它仍可能会引发错误。在执行时检测到的错误被称为异常。

大多数的异常都不会被程序处理,都以错误信息的形式显示出来,并终止程序。

例如:

>>> 10 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> num + 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'num' is not defined
>>> int('abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'abc'

异常是Python对象,表示一个错误。当Python程序发生异常时我们需要捕获处理它,否则程序会终止执行。

10.1.2 异常处理

Python中异常处理的完整形式为:try-except-else-finally

 try:
      "包含可能会抛出异常的代码"
 except:
      "try代码块里的代码如果抛出异常了,该执行什么内容"
 else:
      "try代码块里的代码如果没有抛出异常,就执行这里"
 finally:
      "不管如何,finally里的代码,是总会执行的"

try语句按照如下方式工作:

  • 首先,执行try语句块(在关键字try和关键字except之间的语句)

  • 如果没有异常发生,忽略except语句块,try语句块执行后结束。

  • 如果在执行try 子句时发生了异常,则跳过该子句中剩下的部分。然后,如果异常的类型和 except 关键字后面的异常匹配,则执行 except 子句 ,然后继续执行 try 语句之后的代码。

  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。

一个 try 语句可能包含多个except语句块,分别来处理不同的特定的异常,但最多只有一个分支会被执行。

处理程序将只针对对应的try语句块中的异常进行处理,而不是其他的 try 的处理程序中的异常。

一个except语句块可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

except (RuntimeError, TypeError, NameError):
    pass

最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。例如:10.1-异常.py

import sys

f = None
try:
    f = open("myfile.txt")
except IOError:
    print("Could not find file:myfile.txt")
except KeyboardInterrupt:
    print("You cancelled the reading from the file.")
except BaseException:
    print("Unexpected error:", sys.exc_info()[0])
    raise
else:
    while True:
        line = f.readline()
        if len(line) == 0:
            break
        print(line, end='')
finally:
    if f:
        f.close()
    print("(Cleaning up: Closed the file)")

执行结果为:(假设没有要读取的myfile.txt文件)

Could not find file:myfile.txt
(Cleaning up: Closed the file)

完整结构中的else语句块是可选的,如果使用这个语句块,那么必须放在所有的except语句块之后。这个语句块将在try语句块没有发生任何异常的时候执行。

程序退出之前,finally语句块得到执行,文件对象总会被关闭。

Python中的 raise 语句用于主动抛出一个指定的异常。例如:

>>> raise(TypeError('just test'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: just test