2

I recently discovered the trystatement (I'm pretty new) and I know about except, but I have some questions:

1) How do I use finally?

2) Can you have multiple excepts with different errors?

Could you give me some examples of this?

1

1 Answer 1

1

Answer is yes to everything you ask.

try:
    raise ArithmeticError
except ValueError:
    print("caught valueerror")
except RuntimeError:
    print("caught runtimeerror")
finally:
    print("I'll do this everytime")

Output:

I'll do this everytime

Traceback (most recent call last):
  File "<pyshell#13>", line 2, in <module>
    raise ArithmeticError
ArithmeticError

That's it in short. To get full explanations you best see a tutorial, there's easily million of them online. Some general rules I like to hold to when doing this is:

  • surround the shortest snippet of code you can with the try block. This helps isolate exactly where the error originated.
  • keep your excepts as specific as possible. Try not to catch a generic except as I shown bellow. It's useful sometimes, but so rarely so you should probably try to never do it.
  • finally is always executed. Finally always happens, if an error occurred, if it didn't, if you caught it or if you didn't, finally will always execute. Use it to create a clean exit for your code. Close all open files here, save all data structures you might have and tie all loose ends.

We already saw how finally behaves when you encounter an error you don't have an except for above, here's an example when you raise an error that you have an except for:

try:
    raise ValueError
except ValueError:
    print("caught valueerror")
except RuntimeError:
    print("caught runtimeerror")
finally:
    print("I'll do this everytime")

caught valueerror
I'll do this everytime

Finally will happen even if you don't encounter an error:

try:
    pass
except ValueError:
    print("caught valueerror")
finally:
    print("I'll do this everytime")

I'll do this everytime

There's a couple of ways you can catch any error (try to avoid this, always):

try:
    raise ArithmeticError
except BaseException as e:
    print("caught unknown error: ", e)
finally:
    print("I'll do this everytime")

('caught unknown error: ', ArithmeticError())
I'll do this everytime

or you could do

import sys
try:
    raise ArithmeticError
except:
    print("caught unknown error: ", sys.exc_info()[0])
finally:
    print("I'll do this everytime")

('caught unknown error: ', <type 'exceptions.ArithmeticError'>)
I'll do this everytime

Additionally try except blocks can have an else statement.

Imagine, for a second, a situation where you would want to run some additional code appart from the raise statement. Imagine that code could throw an error too. To put that code inside the same try block would then break my 1st point and that's not how we should do things! To get around that with what I showed so far would look something like:

executed = True
try:
    [do something]
except ValueError:
    executed = False
    print("caught valueerror")
finally:
    print("I'll do this everytime")
    if executed:
        [do something more]

I believe you'll agree that it's ugly and less readable than what python normally strives for. That's why there's an added else statement you can have in your try except block.

else statement must follow all excepts and will only ever execute if there was no error raised. To be really technical, it will only execute "if it flows off the try statement". That means that there must be no returns, breaks, continues and such statements that cause a "jump". else also makes your code neater and more powerful, however I've rarely used it or seen it been used:

try:
    [do something]
    pass
except ValueError:
    print("caught valueerror")
except RuntimeError:
    print("caught runtimeerror")
else:
    [do something more but only if there were no exceptions so far]
    print("I found no errors and executed else statement")
    raise ArithmeticError
finally:
    print("I'll do this everytime")

I found no errors and executed else statement
I'll do this everytime

Traceback (most recent call last):
  File "<pyshell#41>", line 7, in <module>
    raise ArithmeticError
ArithmeticError
Sign up to request clarification or add additional context in comments.

3 Comments

Since the next question is likely to be "how about else?", perhaps you should add an example of how else works here.
@SethMMorton Added, I guess it was silly to pay attention to generic error catching and not have else. Thanks.
else is useful to execute code before a finally that wasn't trapped in an except. Otherwise, I agree that it's use is mostly for clarity, although I use it often for that reason.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.