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_a
、code_b
和 code_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_a
或 code_b
引发异常,code_c
将不会执行。
选项 2
使用 finally:
块:
try:
code_a
code_b
except:
return False
finally:
code_c
return True
如果code_c
在finally:
块中,无论是否有异常都保证执行。
如果没有异常,code_c
在code_a
和code_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
假设如下代码:
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_a
、code_b
和 code_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_a
或 code_b
引发异常,code_c
将不会执行。
选项 2
使用 finally:
块:
try:
code_a
code_b
except:
return False
finally:
code_c
return True
如果code_c
在finally:
块中,无论是否有异常都保证执行。
如果没有异常,code_c
在code_a
和code_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