【问题标题】:Is it possible in Python to write a block of statements such that the entire block is rolled back in case of an exception?是否可以在 Python 中编写一个语句块,以便在发生异常时回滚整个块?
【发布时间】:2014-09-17 18:25:09
【问题描述】:

我的 python 代码看起来像这样 -

try:
    statement1
    statement2
    statement3
except Exception:
    handleException

问题是,如果 statement3 产生异常,statement1 和 statement2 的影响已经发生,我无法在except 部分撤消它们。有没有一种简单的方法来编写类似的东西 -

check if the following block runs without exceptions:
    statement1
    statement2
    statement3
if yes:
    run entire block
if no:
    handleException

(基本上类似于 Python 代码的事务原子性)。

【问题讨论】:

  • 一般来说,没有。如果 statement1 的作用是将数据发送到在线服务器怎么办?没有办法“撤消”它。一般来说,许多可能完成的事情是不可撤销的,或者是不可撤销的。如何回滚一个动作完全取决于那个动作是什么。
  • 事务管理不简单;没有标准的 Python 结构可以为您做到这一点。
  • 您希望不打印print 语句?要取消删除的文件?
  • “不要赌博,把你所有的积蓄都拿出来买一些好股票,等它涨了再卖。如果它不涨,就不要买。 " - 威尔罗杰斯
  • 我不认为 statement1/2/3 是特别复杂的语句。在阅读了 BrenBarn 的评论后,我意识到我刚刚要求的内容并非易事。

标签: python exception exception-handling atomic contextmanager


【解决方案1】:

您的要求是让 Python 做一些事情以查看它是否有效,然后再做,否则,不要一开始就做。这违反了因果关系。

为了处理这类问题,我们通常使用上下文管理器,例如:

with db.transaction():
    entire_block()

如果写得好,它应该在发生异常时为您处理回滚部分。

【讨论】:

    【解决方案2】:

    使用特定的任意语句,不。

    如果您必须进行这样的精细撤消操作,您最好使用命令模式将项目写入块中,并在您进行时为每个操作堆叠一个撤消操作。如果你到了最后并且一切正常,你擦除堆栈,删除所有撤消;如果遇到异常,则将撤消操作逐个从堆栈中弹出并反向执行以恢复原始状态。

    【讨论】:

    • 你能演示一下吗?
    • 目前,不,因为我正在进行其他一些编码,但我可能会在本周晚些时候为您指出一个(微不足道的)示例。然后我会编辑这条评论。
    • 在 SO 上找到了一个有用的墨水来展示这个想法:stackoverflow.com/questions/7509129/…
    猜你喜欢
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2010-09-16
    • 2012-06-28
    相关资源
    最近更新 更多