开发者

Execute (part of) try block after except block

I know that is a weird question, and probably there is not an answer. I'm trying to execute the rest of the try block after an exception was caught 开发者_运维百科and the except block was executed.

Example:

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

do.this() raise an exception managed by foo.bar(), then I would like to execute the code from do.that(). I know that there is not a GOTO statement, but maybe some kind of hack or workaround!

Thanks!


A try... except... block catches one exception. That's what it's for. It executes the code inside the try, and if an exception is raised, handles it in the except. You can't raise multiple exceptions inside the try.

This is deliberate: the point of the construction is that you need explicitly to handle the exceptions that occur. Returning to the end of the try violates this, because then the except statement handles more than one thing.

You should do:

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

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

so that any exception you raise is handled explicitly.


Use a finally block? Am I missing something?

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


If you always need to execute foo.bar() why not just move it after the try/except block? Or maybe even to a finally: block.


One possibility is to write a code in such a way that you can re-execute it all when the error condition has been solved, e.g.:

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


fcts = [do.this, do.that]
for fct in fcts:
    try:
        fct()
    except:
        foo.bar()


You need two try blocks, one for each statement in your current try block.


This doesn't scale up well, but for smaller blocks of code you could use a classic finite-state-machine:

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


Here's another alternative. Handle the error condition with a callback, so that after fixing the problem you can continue. The callback would basically contain exactly the same code you would put in the except block.

As a silly example, let's say that the exception you want to handle is a missing file, and that you have a way to deal with that problem (a default file or whatever). fileRetriever is the callback that knows how to deal with the problem. Then you would write:

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)

Note: I've never seen this design used in practice, but in specific situations I guess it might be usable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜