When using try and except for error handling, does it matter whether you explicitly call finally or if you simply go to a new line that is dedented from the exception code? For example, is there any circumstance under which the two functions below will produce different results?
#Function 1 with finally
def final(x):
try:
print(x*x)
except:
print("Error")
finally:
print("End Function")
#Function 2 with new line dedent
def dedent(x):
try:
print(x*x)
except:
print("Error")
print("End Function")
Update:
Thanks for the explanation of finally running even if there is an error in the except block. One additional thing I wanted to point out is that the finally block will run even if you return an object within the except block. For example, function 3 below will print even after the return while function 4 will not.
#Function 3 with finally
def final(x):
try:
print(x*x)
except:
return 3
finally:
print("End Function 3")
#Function 4 with new line dedent
def dedent(x):
try:
print(x*x)
except:
return 3
print("End Function 4")
test1 = final('test')
test2 = dedent('test')
There is the error in the except block that's been mentioned already:
def final(x):
try:
print(x*x)
except:
print("Error")
damnit
finally:
print("End Function")
def dedent(x):
try:
print(x*x)
except:
print("Error")
damnit
print("End Function")
try:
final("a")
except Exception as e:
print("There was an error:", e)
#>>> Error
#>>> End Function
#>>> There was an error: global name 'damnit' is not defined
try:
dedent("a")
except Exception as e:
print("There was an error:", e)
#>>> Error
#>>> There was an error: global name 'damnit' is not defined
There's also return behaviour:
def final(x):
try:
print(x*x)
except:
print("Error")
return "Return inside"
finally:
print("End Function")
return "Return outside"
def dedent(x):
try:
print(x*x)
except:
print("Error")
return "Return inside"
print("End Function")
return "Return outside"
try:
final("a")
except Exception as e:
print("There was an error:", e)
#>>> Error
#>>> End Function
#>>> 'Return outside'
try:
dedent("a")
except Exception as e:
print("There was an error:", e)
#>>> Error
#>>> 'Return inside'
According to PEP 341:
try: block-1 ... except Exception1: handler-1 ... except Exception2: handler-2 ... else: else-block finally: final-blockThe code in block-1 is executed. If the code raises an exception, the various except blocks are tested: if the exception is of class Exception1, handler-1 is executed; otherwise if it's of class Exception2, handler-2 is executed, and so forth. If no exception is raised, the else-block is executed.
No matter what happened previously, the final-block is executed once the code block is complete and any raised exceptions handled. Even if there's an error in an exception handler or the else-block and a new exception is raised, the code in the final-block is still run.
So as Martjin said, the code in finally will be executed even if the except raises another another error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With