Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it an error to return a value in a finally clause [duplicate]

If I try the following code, I see that the normal block return value is not returned, but the finally block return value is:

>>> def f():
...     try:
...         return "normal"
...     finally:
...         return "finally"
... 
>>> f()
'finally'

A more advanced example is to call a function in each return statement:

In that situation, I can see that:

  • In the normal block, the show function is evaluated (but not return),
  • In the finally block, the show function is evaluated and returned:
>>> def show(x):
...     print(x)
...     return x
... 
>>> def g():
...     try:
...         return show("normal")
...     finally:
...         return show("finally")
... 
>>> g()
normal
finally
'finally'

Is it a good practice the have a return statement in a finally clause? Or, is it a potential error (which should be detected by a code analysis tools or a code review)?

EDIT

Another example with an exception:

>>> def f():
...     try:
...         raise ValueError("bad")
...     finally:
...         return "good"
... 
>>> f()
'good'

Weird!

like image 762
Laurent LAPORTE Avatar asked Oct 15 '19 11:10

Laurent LAPORTE


People also ask

Can we have return statement in finally clause?

Yes, we can write a return statement of the method in catch and finally block. There is a situation where a method will have a return type and we can return some value at any part of the method based on the conditions.

Can you return in a finally block?

Returning from inside a finally block will cause exceptions to be lost. A return statement inside a finally block will cause any exception that might be thrown in the try block to be discarded.

Can finally block return value?

Yes you can write the return statement in a finally block and it will override the other return value. The output is always 2, as we are returning 2 from the finally block.

Does return override finally?

Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java. If we call the System. exit() method explicitly in the finally block then only it will not be executed.


1 Answers

IMHO, having a return in a finally clause is bad practice if there is a return statement in the related try or except blocks.

try:
    # lots of spaghetti code
    return fancy_expression_with_side_effects
except AllKindsOfError:
    # lots of alternative spaghetti code
finally:
    # many a mouse wheel spin down the module
    # lots of clean up
    return eternal_return_value

While this would constitute valid Python, it really should't. The first return statement will partially execute: you will observe the side effects of evaluating fancy_expression_with_side_effects (try return print('foo') there) and it will still not return that expression's value. I have once scratched my head for a couple of hours in that exact situation.

If, however, the return statement in the finally is the only return statement, one will be able to easily follow the step-by-step execution flow in a simple expected manner and I don't see too much fault in it, but would stilll be very careful: In many software projects, you might be the senior Python guy who knows such stuff, but what guarantee do you have that no one else will add a return statement elsewhere later on?

like image 124
user2390182 Avatar answered Sep 29 '22 11:09

user2390182