在引发之前恢复python尝试异常块中的更改

Posted

技术标签:

【中文标题】在引发之前恢复python尝试异常块中的更改【英文标题】:Revert changes in python try exception block before raising 【发布时间】:2021-11-14 04:09:55 【问题描述】:

我需要更新对象的一个​​属性以进行单次验证。在任何情况下,我都需要在验证引发错误之前恢复它。 如果这实际上是在引发异常之前还原某些内容的最漂亮方法,我目前感到困惑,因为那时我必须复制还原代码。 finally 在这里不起作用,因为它在 raise 语句之后执行。

amount = instance.amount
instance.amount = 0
try:
    validate_instance(instance)
except Exception:
    instance.amount = amount
    raise
else:
    instance.amount = amount

【问题讨论】:

在您的代码块中,您的意思是始终将其恢复为旧值amount,无论是否有异常?因为它存在于exceptelse executed after the raise statement 是什么意思?在我对try:except:finally: 的实验中,finallyraise 使控制离开当前功能之前执行。 【参考方案1】:

最后block应该没问题了,如下图:

amount = 15

def throw_me_an_error():
    try:
        amount = 20
        print("I've set the amount to 20.")
        test = 'hey' + 1
    except Exception as e:
        print('Exception thrown')
        raise e
    else:
        print('Else part')
    finally:
        amount = 15
        print('I reverted the amount to 15.')
        print('Finally!')
        
try:
    throw_me_an_error()
except Exception:
    print('An exception was thrown')
    
print(f'The amount is now amount')

结果

I've set the amount to 20.
Exception thrown
I reverted the amount to 15.
Finally!
An exception was thrown
The amount is now 15

【讨论】:

最终确实可以正常工作,我认为它的工作方式会有所不同 “finally”中的部分在错误被抛出给调用您的功能的父代码之前执行(更新了我的答案,使其更加可见)。【参考方案2】:

正如其他答案中所指出的,finally 确实可以正常工作:

>>> try:
...     try:
...         print(1)
...         x += 1
...     except Exception:
...         raise
...     finally:
...         print(2)
... except Exception:
...     print(3)
... 
1
2
3

【讨论】:

以上是关于在引发之前恢复python尝试异常块中的更改的主要内容,如果未能解决你的问题,请参考以下文章

从完成处理程序/块中引发自定义异常会使目标 c 中的应用程序崩溃

为啥在匿名 PL/SQL 块中没有立即引发异常?

如何从 PowerShell 中的 catch 块中重新引发异常?

在 PHP Try Catch 块中抛出异常

finally 块中的异常

确定哪个方法引发异常