9

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?

7
  • I'd assume the else is a general purpose "if no except clause caught an exception, run the code here". Commented Nov 15, 2011 at 1:15
  • here is the answer: stackoverflow.com/questions/855759/python-try-else Commented Nov 15, 2011 at 1:16
  • 1
    @slugonamission it is, but what's the real-world use of that? Commented Nov 15, 2011 at 1:17
  • 3
    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. Commented Nov 15, 2011 at 1:20
  • 1
    well, first you need exception handling in C Commented Nov 15, 2011 at 4:52

3 Answers 3

9

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Your example is very readable and demonstrates a realistic use case. Great answer!
You said "That is its one use-case for which there isn't a reasonable alternative." but you didn't give any use-case (to which "that" could refer)...
When introducing your only example, you just repeat what else: does (runs its code before finally if there is no exception in try, as you have already said before, and as known from the documentation), but the example would work the same if the else: part was inside try:, so it does not provide any (interesting) use-case either.
4

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.

1 Comment

I see. I'm not used to it so it sounds a bit unreadable. But agreed, both try and finally blocks should be kept as short as possible. So in the case you need stuff between them, else is good.
0

If a future reader stumbles on this post and would like another example; I have one for you. During my thesis, I ended up building the following try-except-else-finally statement.

I'm carrying out numerous numerical simulations. Each simulation I save using pickle. These simulations I carry out on a High Performance Cluster (HPC). For some reason, some pickle files end up corrupted since a few weeks. These files I do not want to save and I rather delete them.

for i range(n_simulations):
   data = simulate()

   # Save simulation data using my custom method
   filepath = save_to_pickle(data)
 
   # Custom class to reload my pickles during data processing later
   data_loader = DataLoad()
   
   # Checking if file is corrupted using the same data loader class
   try:
        data_loader.load_file(filepath)

   except Badzipfile:
       print('File is corrupted, deleting')
       delete_saved_file(filepath)

   else:
       print('Simulation success') 

   finally:
       del data_loader

Comments

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.