首页 > 解决方案 > Python中异常处理中的异常

问题描述

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

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

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

这通常是真的吗?此外,在这种情况下,可能会在错误处理内部引发多个异常,这些异常都由外部 except 块处理,是否有办法让外部 except 块分别遍历每个错误?

标签: pythonexception

解决方案


Python 文档有这个:

如果在 try 子句执行期间发生异常,则该异常可以由 except 子句处理。如果异常未由 except 子句处理,则在 finally 子句执行后重新引发异常。

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

这类似于returning 中的函数finally

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

可以获得有关原始异常的一些信息。从文档

当在 except 或 finally 子句上下文中引发(或重新引发)异常时,将自动设置为最后一个捕获的异常;如果未处理新异常,则最终显示的回溯将包括原始异常和最终异常。

所以:

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

# prints: "division by zero"

推荐阅读