Python’s “try except else finally” explained

In Python it’s okay to make assumptions, as long as you’re able to clean up the mess if they turn out to be wrong. In fact, this is not only okay but considered good practice.

Real life example: dogs & cats

This section is for people who want to learn about the basic try/except control structure. More experienced Pythonistas could skip down to the last section of this blog post, although they would miss one hell of an awesome example.

Image for post
Image for post

I am a “dog person”. Nothing against cats — I can definitely see the appeal. Just not for me ;)

Now imagine I’m walking down the sidewalk and some leashed animal is walking towards me, but I can’t quite tell if it’s a dog or a cat.

If it’s a dog I will ask if I can pet it, but if it’s a cat then I’m not interested.

There are two ways of expressing this logic.

1. Using if/else

is_dog = check_if_dog()
if is_dog:
pet_dog()
else:
ignore_animal()

2. Using try/except

try:
pet_dog()
except:
ignore_animal()

In Python it’s often preferable to do option #2, and you can see examples of this “in the wild” wherever you look.

The try/except control flow

Here I’ll walk through a far more concrete example.

The first time I ran into Python’s try/except was when reading web-scraper code.

The code went something like this:

try:
print("Parsing div text")
data_div_text = soup.find("div", {"id": "data-div"}).text
except:
print("No text found")

By the way, what would have come before this snippet is (a) getting the web page and (b) instantiating a BeaitfulSoup object, above referenced with the variable soup.

The idea here is simple: if the <div> with id=”data-div” is found then parse its text, and otherwise print that nothing was found.

The try/except/else/finally control flow

Now let’s introduce two lesser-known tools Python provides for this control flow structure: else and finally.

Consider this example, where we log results to a file.

try:
print("Parsing div text")
data_div_text = soup.find("div", {"id": "data-div"}).text
except:
print("No text found")
else:
with open("data_div_text.txt", "w") as f:
f.write(data_div_text)
finally:
print("Done parsing div text")

The first 5 lines are identical to what we had before.

Understanding else/finally is simple because there are only two cases.

  1. The try statement succeeds
    -> The except statement is skipped
    -> The else statement runs
    -> The finally statement runs
  2. The try statement fails
    -> The except statement runs
    -> The else statement is skipped
    -> The finally statement runs

The idea in my example above is to write the div text to a file only if it’s found on the page. It’s important to do this after the try block runs, to avoid the except block catching any file handling error that may arise.

Is else/finally even useful?

It’s pretty rare to find else in the wild when looking at try/except conditions, and even less common to find finally.

The consensus seems to be that else/finally usually aren’t that useful.

I showed a decent example of else above, and others I have seen work along similar lines.

The finally statement is probably best understood in terms of code readability, since it offers a nice way of grouping similar logic within the same control flow structure.

What do you think? Let me know in a comment or on twitter.

Conclusion

In this post I shared my thoughts on dogs VS cats.

Oh yeah and some Python stuff about control flow structures… whatever.

As always, thanks for reading. Now get back to your code! Your projects are missing you ;)

https://alexgalea.ca/

Written by

Python Data Engineer, MSc. Physics

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store