Python 异常处理中的异常

时间:2021-07-05 23:20:29

标签: python exception

我试图了解 Python 如何在异常处理中处理异常。例如,请考虑以下内容:

try:
    try:
        1/0
    finally:
        raise Exception("Exception!")
except Exception as e:
    print(e)

我的理解是,这段代码抛出的两个异常(ZeroDivisionError 和 finally 块中抛出的通用异常)都应该由除了块之外的外部“处理”……但是 Python 如何决定分配给哪个异常e?在我的机器上运行代码,似乎Python选择将“最近的”异常(finally块中抛出的那个)分配给e。

这通常是真的吗?此外,在这种情况下,在错误处理中可能会抛出多个异常,而这些异常都由外部 except 块处理,有没有办法让外部 except 块分别单步处理每个错误?

1 个答案:

答案 0 :(得分:2)

Python docs 有这个:

<块引用>

如果在 try 子句执行过程中发生异常,则 异常可以由except子句处理。如果异常不是 由except子句处理,异常在 finally 子句已执行。

因此,在您的示例中,您没有捕获内部异常,这会导致 finally 块执行(在重新引发原始异常之前)。 finally 中的异常在有机会重新引发原始异常之前将其踢到外部块。外部块永远不会看到被零除异常。

这类似于 return 中的函数的 finallying:

def ex_test():
    try:
        try:
            1/0
        finally:
            return "finally"
    except Exception as e:
        print(e) # never gets here

ex_test()
# only prints "finally"
# never re-raises the exception

可以获得一些关于原始异常的信息。来自the docs

<块引用>

在except或finally中引发(或重新引发)异常时 context 子句自动设置为最后捕获的异常; 如果新的异常没有被处理,那么最终的回溯 显示的将包括原始异常和最终异常 例外。

所以:

try:
    try:
        1/0
    finally:
        raise Exception("Exception!")
except Exception as e:
    print(e.__context__)

# prints: "division by zero"