8
votes

I'm trying to learn the minor details of Python, and I came upon the try-else statement.

try1_stmt ::=  "try" ":" suite
               ("except" [expression [("as" | ",") target]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]

The optional else clause is executed if and when control flows off the end of the try clause. Exceptions in the else clause are not handled by the preceding except clauses.

I can't think of a case where this would be useful. Usually there's no practical difference between putting code in the end of the try block or in the else block.

What is the else clause good for? Is it used in some real-world code?

2
I'd assume the else is a general purpose "if no except clause caught an exception, run the code here". - slugonamission
@slugonamission it is, but what's the real-world use of that? - StackExchange saddens dancek
Actually, I'm an idiot (and should read the manual first). As the other link says (from Emir), it's for code you only want to execute without error handling on success before the finally block is run. - slugonamission
well, first you need exception handling in C - wim

2 Answers

9
votes

Usually there's no practical difference between putting code in the end of the try block or in the else block.

What is the else clause good for?

The else-clause itself is interesting. It runs when there is no exception but before the finally-clause. That is its one use-case for which there isn't a reasonable alternative.

Without the else-clause, the only option to run additional code before finalization would be the clumsy practice of adding the code to the try-clause. That is clumsy because it risks raising exceptions in code that wasn't intended to be protected by the try-block.

The use-case of running additional unprotected code prior to finalization doesn't arise very often. So, don't expect to see many examples in published code. It is somewhat rare.

Another use-case for the else-clause it to perform actions that must occur when no exception occurs and that do not occur when exceptions are handled. For example:

   recip = float('Inf')
   try:
       recip = 1 / f(x)
   except ZeroDivisionError:
       logging.info('Infinite result')
   else:
       logging.info('Finite result')

Lastly, the most common use of an else-clause in a try-block is for a bit of beautification (aligning the exceptional outcomes and non-exceptional outcomes at the same level of indentation). This use is always optional and isn't strictly necessary.

Is it used in some real-world code?

Yes, there are a number of examples in the standard library.

4
votes

Having 'extra' stuff in the end of the try block is, at least in my opinion, a bit of a code smell. The try block should contain only the line(s) which you think are at risk of throwing an exception, preferably just a single line.

This avoids any case of accidentally catching an exception from a line which you weren't suspecting might throw (and possibly handling it inappropriately). The else block allows you to code this in a cleaner way.