Python引发和处理异常

示例

这是Python语法2,注意逗号,上raise和except线:

Python 2.x 2.3
try:
    raise IOError, "input/output error"
except IOError, exc:
    print exc

在Python 3中,,语法已删除,并由括号和as关键字替换:

try:
    raise IOError("input/output error")
except IOError as exc:
    print(exc)

为了向后兼容,Python 3语法也可以在Python 2.6及更高版本中使用,因此应将其用于不需要与先前版本兼容的所有新代码。


Python 3.x 3.0

Python 3还添加了异常链接,您可以在其中发出信号,说明其他异常是导致此异常的原因。例如

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from e

except语句中引发的异常的类型为DatabaseError,但是原始异常被标记__cause__为该异常的属性。当显示回溯时,原始异常也将显示在回溯中:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

如果在没有显式链接的情况下抛出一个except块:

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}')

追溯是

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
FileNotFoundError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
Python 2.x 2.0

Python 2.x均不支持。如果在except块中引发另一个异常,则原始异常及其追溯将丢失。以下代码可用于兼容性:

import sys
import traceback

try:
    funcWithError()
except:
    sys_vers = getattr(sys, 'version_info', (0,))
    if sys_vers < (3, 0):
        traceback.print_exc()
    raise Exception("new exception")
Python 3.x 3.3

要“忘记”以前抛出的异常,请使用 raise from None

try:
    file = open('database.db')
except FileNotFoundError as e:
    raise DatabaseError('Cannot open {}') from None

现在回溯将只是

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')

或者,为了使其与Python 2和3兼容,您可以使用以下六个包:

import six
try:
    file = open('database.db')
except FileNotFoundError as e:
    six.raise_from(DatabaseError('Cannot open {}'), None)