What's try-else good for in Python?

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?

Upvotes: 9

Views: 3116

Answers (3)

HerChip
HerChip

Reputation: 123

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

Upvotes: 0

Raymond Hettinger
Raymond Hettinger

Reputation: 226296

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.

Upvotes: 9

wim
wim

Reputation: 362697

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.

Upvotes: 4

Related Questions