【问题标题】:Execute (part of) try block after except block在 except 块之后执行(部分)try 块
【发布时间】:2010-11-19 14:26:38
【问题描述】:

我知道这是一个奇怪的问题,而且可能没有答案。 在捕获到异常并执行了 except 块后,我正在尝试执行 try 块的其余部分。

例子:

[...]
try:
 do.this()
 do.that()
 [...]
except:
 foo.bar()
[...]

do.this() 引发由foo.bar() 管理的异常,然后我想执行来自do.that() 的代码。我知道没有 GOTO 语句,但可能是某种 hack 或解决方法!

谢谢!

【问题讨论】:

  • 这表明你的设计有问题。如果do.that 可以在do.this 引发异常的情况下运行,那么它们不应该在同一个try-except-block 中。您必须提供有关函数实际执行的信息,以便我们提出解决方案。

标签: python exception-handling


【解决方案1】:

try... except... 块捕获 一个 异常。这就是它的用途。它执行 try 中的代码,如果引发异常,则在 except 中处理它。您不能在 try 中引发多个异常。

这是故意的:构造的重点是您需要明确来处理发生的异常。返回到try 的末尾违反了这一点,因为except 语句处理不止一件事。

你应该这样做:

try:
    do.this()
except FailError:
    clean.up()

try:
    do.that()
except FailError:
    clean.up()

以便显式处理您引发的任何异常。

【讨论】:

    【解决方案2】:

    使用 finally 块?我错过了什么吗?

       [...] 
        try: 
         do.this() 
        except: 
         foo.bar() 
        [...] 
        finally:
         do.that()
         [...] 
    

    【讨论】:

    • 我的问题并不清楚。实际上,异常可以从 this() 或 that() 或任何地方引发,它并不关心,但关键是以某种方式“返回”到 try 块。异常后“返回”或以某种方式执行try块中的代码
    【解决方案3】:

    如果你总是需要执行foo.bar(),为什么不把它移到try/except块之后呢?或者甚至是finally: 块。

    【讨论】:

    • 我不需要总是执行 foo.bar()。那只是一个例子。我正在尝试做的是在执行 except: 块后返回 try: 块
    • @Niko P,如果引发异常,您将无法返回到 try 块。但是您可以重组您的代码,这样就不需要了。
    • 我知道我无法返回到 try 块。但是假设我能够在运行时修复 do.this() (或该 try 块中的任何其他操作),我该如何恢复执行?只拆分 try/execute 块中的每个调用?
    【解决方案4】:

    一种可能性是编写代码,以便在错误条件解决后重新执行所有代码,例如:

    while 1:
       try:
          complex_operation()
       except X:
          solve_problem()
          continue
       break
    

    【讨论】:

    • 这样重新运行所有的 try: 块。我想从失败指令的下一条指令重新开始执行。
    • 这就是为什么我说“以您可以重新执行所有代码的方式编写代码”,例如不需要重新获取资源的代码,诸如此类。好吧,只是一个想法。
    【解决方案5】:
    fcts = [do.this, do.that]
    for fct in fcts:
        try:
            fct()
        except:
            foo.bar()
    

    【讨论】:

      【解决方案6】:

      您需要两个 try 块,一个用于当前 try 块中的每个语句。

      【讨论】:

        【解决方案7】:

        这不能很好地扩展,但对于较小的代码块,您可以使用经典的有限状态机:

        states = [do.this, do.that]
        state = 0
        while state < len(states):
            try:
                states[state]()
            except:
                foo.bar()
            state += 1
        

        【讨论】:

          【解决方案8】:

          这是另一种选择。使用回调处理错误情况,以便在修复问题后可以继续。回调基本上包含与您放入 except 块中的代码完全相同的代码。

          作为一个愚蠢的例子,假设您要处理的异常是丢失的文件,并且您有办法处理该问题(默认文件或其他)。 fileRetriever 是知道如何处理问题的回调。然后你会写:

          def myOp(fileRetriever):
          
              f = acquireFile()
              if not f:
                  f = fileRetriever()
          
              # continue with your stuff...
          
              f2 = acquireAnotherFile()
              if not f2:
                  f2 = fileRetriever()
          
              # more stuff...
          
          
          myOp(magicalCallback)
          

          注意:我从未在实践中看到过这种设计,但在特定情况下我猜它可能是可用的。

          【讨论】:

            猜你喜欢
            • 2022-11-12
            • 1970-01-01
            • 2022-11-02
            • 2021-05-13
            • 1970-01-01
            • 2020-08-19
            • 1970-01-01
            • 2020-12-11
            • 2018-08-21
            相关资源
            最近更新 更多