From the Python documentation
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement. A more complicated example (having except and finally clauses in the same try statement works as of Python 2.5):
So once the try/except block is left using return, which would set the return value to given - finally blocks will always execute, and should be used to free resources etc. while using there another return - overwrites the original one.
In your particular case, func1() returns 2 and func2() returns 3, as these are values returned in the finally blocks.
Ok, that was an awful title and I'm sorry... but it's hard to phrase! My question overall is, if we use a try statement in a function (and let's imagine it works, we don't end up having to handle any exceptions) and there is a return statement in this try-block. Won't that cause us to leave the function? Since, we are returning control back to main, let's say.
But, we have a finally statement in our function to. It might do something trivial like print something. Does this get executed even though we should have hit return?
Now, I have tested this. And what it seems to do is reach the return statement, ignore it, carry out the finally statement and then go back to the return. But I would like to know if I am understanding this correctly.
From the Python documentation
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement. A more complicated example (having except and finally clauses in the same try statement works as of Python 2.5):
So once the try/except block is left using return, which would set the return value to given - finally blocks will always execute, and should be used to free resources etc. while using there another return - overwrites the original one.
In your particular case, func1() returns 2 and func2() returns 3, as these are values returned in the finally blocks.
It will always go to the finally block, so it will ignore the return in the try and except. If you would have a return above the try and except, it would return that value.
def func1():
try:
return 1 # ignoring the return
finally:
return 2 # returns this return
def func2():
try:
raise ValueError()
except:
# is going to this exception block, but ignores the return because it needs to go to the finally
return 1
finally:
return 3
def func3():
return 0 # finds a return here, before the try except and finally block, so it will use this return
try:
raise ValueError()
except:
return 1
finally:
return 3
func1() # returns 2
func2() # returns 3
func3() # returns 0
Python confusion with return value in try-except-finally - Stack Overflow
Run code finally before returning in except
Python function with try, except, finally, and return
What will happen in this try except?
You're running into the difference between an identifier and a value. num += 1 is creating a new int object and assigning the num identifier to point to it. It does not change the int object the identifier is already pointing to. (For small values the int objects are cached but that's an implementation detail)
You can see the difference with an operation that does mutate the object in the below code:
def y():
l = []
try:
raise Exception
except Exception:
print("except")
l.append(1)
return l
finally:
print("finally")
l.append(2)
print(y())
# except
# finally
# [1, 2]
The finally is executed (this is clearly defined in the documentation), but as you return an immutable object, the modification is unseen as your returned name is now part of a different scope.
This would work as you expect with a mutable object, for instance a list:
def main():
lst = [0]
try:
raise Exception('This is the error message.')
except Exception:
lst[0] += 1
return lst
finally:
lst[0] += 1
a = main()
print(a)
Output: [2]
def func():
try:
a = 1 / 0 # This will raise a ZeroDivisionError
return a
except ZeroDivisionError as e:
raise e # Reraise the exception
return -1
finally:
return "finally"The answer is: the function returns 'finally'
In Python, the finally block always executes, regardless of whether there’s an exception, a return statement, or anything else happening in the try or except blocks. If the finally block contains a return statement, it takes precedence over everything else, including exceptions and other return statements. Swallowing an exception like this without any warning feels dangerous.
Do you think this expected behavior? How do other programming languages handle this?
I understand the concept of try: except: block or try: except: else: but I don't seem to understand purpose of the finally: block.Is there a difference between:
try:
*try something*
except:
*catch and handle error
finally:
*continue rest of the script*And:
try:
*try something*
except:
*catch and handle error
*continue rest of the script without 'finally' block*I suppose there must be some difference,but I can't find any
http://docs.python.org/reference/compound_stmts.html#the-try-statement
The optional else clause is executed if and when control flows off the end of the try clause.
Currently, control “flows off the end” except in the case of an exception or the execution of a return, continue, or break statement.
The reason for this behaviour is because of the return inside try.
When an exception occurs, both finally and except blocks execute before return. Otherwise only finally executes and else doesn't because the function has already returned.
This works as expected:
def divide(x, y):
print 'entering divide'
result = 0
try:
result = x/y
except:
print 'error'
else:
print 'no error'
finally:
print 'exit'
return result
print divide(1, 1)
print divide(1, 0)