2

Possible Duplicate:
Purpose of else and finally in exception handling

I'd like to understand why the finally clause exists in the try/except statement. I understand what it does, but clearly I'm missing something if it deserves a place in the language. Concretely, what's the difference between writing a clause in the finally field with respect of writing it outside the try/except statement?

Community
  • 1
  • 1
chuse
  • 373
  • 3
  • 18
  • 1
    Code below finally runs even if the exception isn't caught, which is good for, say, closing files, sockets, etc. – Gonzalo Jul 30 '12 at 13:49
  • It deserves a place in the language because you don't want your program to continue running after an error but you will obviously want to close files or connections. http://www.linuxtopia.org/online_books/programming_books/python_programming/python_ch17s05.html – jamylak Jul 30 '12 at 13:50
  • 1
    Also see [Why do we need the "finally" statement in Python?](http://stackoverflow.com/q/11551996) – Martijn Pieters Jul 30 '12 at 13:56
  • @jamylak I understand you want to clean up, what was not clear is why you cannot do it outside the `try/except`. – chuse Jul 30 '12 at 14:02

2 Answers2

14

The finally suite is guaranteed to be executed, whatever happens in the try suite.

Use it to clean up files, database connections, etc:

try:
    file = open('frobnaz.txt', 'w')
    raise ValueError
finally:
    file.close()
    os.path.remove('frobnaz.txt')

This is true regardless of whether an exception handler (except suite) catches the exception or not, or if there is a return statement in your code:

def foobar():
    try:
        return
    finally:
        print "finally is executed before we return!"

Using a try/finally statement in a loop, then breaking out of the loop with either continue or break would, again, execute the finally suite. It is guaranteed to be executed in all cases.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    +1 great answer - example shows that an exception can be raised by some code, but still provide for cleanup before the exception is propagated... exactly the purpose of `finally`. – Rob I Jul 30 '12 at 13:52
  • Why aren't exceptions re-raised if `finally` contains a `return`, `break` or `continue`? – user51462 Aug 11 '22 at 14:06
  • @user51462: because the exception is re-raised as the final action of the `finally` block. This works exactly like `return` in a function, or `break` or `continue` in a loop would skip statements that follow. – Martijn Pieters Aug 11 '22 at 20:49
  • Thank you @MartijnPieters, would you have any insight into why the designers didn't choose to do it the other way around and re-raise the exception just before the control flow statement? Especially since the style guide (see [here](https://peps.python.org/pep-0008/#id51:~:text=Use%20of%20the%20flow,through%20the%20finally%20suite%3A)) recommends *against* using control flow statements in `finally`. If someone wants to stop propagation, why not just use `except: pass`? – user51462 Aug 13 '22 at 11:35
  • @user51462 Sorry, no insights. To me it has the sense of an accidental implementation detail preserved for compatibility reasons but I have no evidence for that. I don’t have the time right now to do further research, sorry. – Martijn Pieters Aug 13 '22 at 12:02
2

The finally clause will always execute which is great if you missed an exception type in your code.

To quote the documentation:

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.

Christian Witts
  • 11,375
  • 1
  • 33
  • 46