try/except 语句中是否可以在不跳过 try 子句的其余部分的情况下发生异常?

Can an exception occur in a try/except statement without skipping the rest of the try clause?

假设如下代码:

try:
    code_a
    code_b
    code_c
except:
    pass

如果code_b发生错误,那么它会被except捕获,只有code_a会有运行。有没有办法确保 code_c 运行 也一样?

我想:

try: 
    code_a
except: 
    pass
try: 
    code_b
except: 
    pass
try: 
    code_c
except: 
    pass

这不是正确的做法。

你可以使用“finally”:

try:
    print(1)
    print(some nonexistent variable)
except:
    pass
finally:
    print(3)

这将打印“1”和“3”

您的标题问题的简短答案是否定的。try: 块的其余部分将不会在异常后执行。

正如您所注意到的,您可以将 code_acode_bcode_c 放在它们自己的 try: 块中并分别处理错误。

您询问 code_c 是否可以 运行 即使 code_b 引发异常。

选项 1

code_c 完全放在 try: 块之外:

try:
    code_a
    code_b
except:
    pass
code_c

但要小心。 code_c肯定不会执行。这取决于 except: 块中的内容。考虑以下示例:

try:
    code_a
    code_b
except:
    return False
code_c
return True

如果 code_acode_b 引发异常,code_c 将不会执行。

选项 2

使用 finally: 块:

try:
    code_a
    code_b
except:
    return False
finally:
    code_c
return True

如果code_cfinally:块中,无论是否有异常都保证执行。

如果没有异常,code_ccode_acode_b之后执行。

如果出现异常,return False 将按预期工作,但 code_c 将挤入并在函数 returns 之前执行。这是因为保证执行.

完整示例

def ham():
    print('Ham please')


def eggs():
    print('Eggs please')
    raise NoEggsException


class NoEggsException(Exception):
    pass


def spam():
    print('Spam Spam Spam Spam Spam!')


def order():
    try:
        ham()
        eggs()
    except NoEggsException:
        print('    ...no eggs :(')
        return False
    finally:
        spam()
    return True


if __name__ == '__main__':
    order_result = order()
    print(f'Order complete: {order_result}')

当运行如写时,eggs()引发异常。结果如下:

Ham please
Eggs please
    ...no eggs :(
Spam Spam Spam Spam Spam!
Order complete: False

请注意,即使 except: 块中有 return False,也会执行 spam()(在 finally: 块中)。

以下是 raise NoEggsException 被注释掉或删除时发生的情况:

Ham please
Eggs please
Spam Spam Spam Spam Spam!
Order complete: True

请注意,无论哪种方式,您都会在订单中收到 spam (and more spam)。