开发者

How to execute something if any exception happens

开发者 https://www.devze.com 2023-01-24 17:55 出处:网络
A python newbie question: I need to do the following try: do-something() except error1: ... except error2:

A python newbie question: I need to do the following

try:
  do-something()
except error1:
  ...
except error2:
  ...
except:
  ...
#Here I need to do something if any exception of t开发者_开发百科he above exception was thrown.

I can set a flag and do this. But is there a cleaner way of doing this?


Actually I don't like flags and consider them as the last resort solution. In this case I'd consider something like this:

def f():
  try:
    do_something()
  except E1:
    handle_E1()
  except E2:
    handle_E2()
  else:
    return
  do_stuff_to_be_done_in_case_any_exception_occurred()

Of course, this is only an option if you can return in the else: case.

Another option might be to rethrow the exception and recatch it for a more general handling of errors. This might even be the cleanest approach:

def f():
  try:  # general error handling
    try:  # specific error handling
      do_something()
    except E1:
      handle_E1()
      raise
    except E2:
      handle_E2()
      raise
  except (E1, E2):
    do_stuff_to_be_done_in_case_any_exception_occurred()


I just tried a couple different idea's out and it looks like a flag is your best bet.

  • else suite is only called if there is no exception
  • finally will always be called


You can do this with a nested try. The except block of the outer try should catch all exceptions. Its body is another try that immediately re-raises the exception. The except blocks of the inner try actually handle the individual exceptions. You can use the finally block in the inner try to do what you want: run something after any exception, but only after an exception.

Here is a little interactive example (modeled on Applesoft BASIC for nostalgia purposes).

try:
    input("]")  # for Python 3: eval(input("]"))
except:
    try:
       #Here do something if any exception was thrown.
       raise
    except SyntaxError:
       print "?SYNTAX",
    except ValueError:
       print "?ILLEGAL QUANTITY",
    # additional handlers here
    except:
       print "?UNKNOWN",
    finally:
       print "ERROR"


This is the best way I can think of. Looks like a code smell though

try:
  exception_flag = True
  do-something()
  exception_flag = False
except error1:
  ...
except error2:
  ...
except:
  ...
finally:
  if exception_flag:
    ...

You wouldn't need the finally if you are not reraising exceptions in the handler


From the docs: http://docs.python.org/reference/compound_stmts.html#finally

If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is lost. The exception information is not available to the program during execution of the finally clause.


It's not clear if you need to handle differently error1, error2 etc. If not, then the following code will do the trick:

try:
    do_something()
except (error1, error2, error3), exception_variable:
    handle_any_of_these_exceptions()

if you do need to handle different errors differently as well as having the common code, then in the except block, you can have code of the following type:

    if isinstance(exception_variable, error1):
       do_things_specific_to_error1()


I think this is a more neat solution by using return in the try clause. If everything works, we will return the value we got in bar(). If we get an exception, we will run the next code, in this case raising another exception. Demonstrated with a randint.

import random

def foo():
    try:
        return bar()
    except IndexError:
        print('Error.')
    raise KeyError('Error msg')
    
def bar():
    res = random.randint(0, 2)
    if res == 0:
        raise IndexError
    return res

res = foo()
print(res)
0

精彩评论

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