3

I have two questions on exception handling.

Q1) I am slightly unsure as to when exactly the operations within else will be carried out in exception handling. I am unsure when the else block would be executed, which doesn't occur in the code below:

def attempt_float(SecPrice,diffprice):
    try:
        return float(SecPrice)
    except:
        return diffprice
    else: 
        print "Did we succeed?"

print attempt_float('7','3') 

Q2) When I run the code below:

def attempt_float(SecPrice,diffprice):
    try:
        return float(SecPrice)
    except:
        return diffprice
    else: 
        print "Did we succeed?"
    finally:
        print "Yasdsdsa"

print attempt_float('7','3')

I am unclear as to why the output is:

Yasdsdsa
7.0
2
  • 1
    You return in the try, so you never hit else Commented Dec 10, 2014 at 1:15
  • possible duplicate of Python try-else Commented Dec 10, 2014 at 1:17

2 Answers 2

2

When Python encounters a return-statement inside a function, it immediately returns (exits) from the function. This means that when you do:

try:
    return float(SecPrice)
...
else: 
    print "Did we succeed?"

"Did we succeed?" will never be printed because you returned in the try: block, thereby skipping the execution of the else: block.


Your second code piece is different however because you used a finally: block. Code inside a finally: block is always executed, no matter if an exception is raised, you return from a function, etc. This is to ensure that any cleanup code which is important (i.e. frees resources) is always executed and not accidentally skipped.

You can read about this behavior in the docs both here:

When return passes control out of a try statement with a finally clause, that finally clause is executed before really leaving the function.

as well as here:

When a return, break or continue statement is executed in the try suite of a try...finally statement, the finally clause is also executed "on the way out."


As for why the output is:

Yasdsdsa
7.0

and not:

7.0
Yasdsdsa

the answer is that the print "Yasdsdsa" line is executed in the finally: block before Python is able to print 7.0 (the return value of attempt_float). Put simply, the execution path for Python is:

  1. Return float(SecPrice).
  2. Run the finally: block.
  3. Resume normal execution with the print attempt_float('7','3') line and print 7.0.
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I'm mainly confused as to why the output is in this order: Yasdsdsa 7.0 rather than the other way around.
2

In the first case, you return within try, so you never hit the else statement.

In the second one, the finally is executed regardless of how try is exited. From the python docs:

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. (...) 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.

Here is a good example of the order of execution:

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print "division by zero!"
...     else:
...         print "result is", result
...     finally:
...         print "executing finally clause"
...
>>> divide(2, 1)
result is 2
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause

Be sure to read the docs on exceptions!

2 Comments

Thanks. If the finally only executes "on the way out" why is the output in this order: Yasdsdsa 7.0 rather than the other way around.
Because you are printing the returned value from attempt_float, but before it returns, the finally block is executed.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.