The basics of exceptions in Python 3

I had a recent assignment from my Programming module, where I was tasked to build a simple command-line program in Python 3 that emulated a database. After delving into it and trying to find the best way to go about building this program, I realized the importance of gracefully handling exceptions in Python. I also created a few of my own, which drastically improved the readability and maintainability of my code. In this article, I will demonstrate how exceptions work and how to use them, based on what I discovered during the assignment.

Note: Stack traces are removed from the console output as they are usually long and will clutter this post.

Introduction

Exceptions occur when something unexpected happens in your code. Some common examples include:

  • When you try to access an element that doesn’t exist within a list
a_list = [1, 2, 3]
print(a_list[1000000])
# IndexError: list index out of range
  • When you try to access a key that doesn’t exist in a dictionary
a_dict = {'hello': 'world'}
print(a_dict['doesn't exist'])
# KeyError: 'doesn't exist'
  • Even when you try to run invalid syntax, it’s actually just an exception
a_dict = {'hello': 'world}
# no quote here ^
# SyntaxError: EOL while scanning string literal

The term used when describing these is ‘raised’. These exception were raised by your code, be it directly in your code, or in the functions that your code called. To show this, a simple program can be created:

print('Before exception')
raise Exception
print('After exception')
# Console output:
#
# Before exception
# Exception

Notice how the program stops after we raise the exception. This is because our program has crashed (This will be described in further detail later on). An optional error description can be added, to make the error message be more descriptive.

print('Before exception')
raise Exception('My cool exception!')
print('After exception')
# Console output:
#
# Before exception
# Exception: My cool exception

Try, Except, Else, Finally

Sometimes, we want to use exceptions to our advantage. In the previous section, all we did was to raise exceptions and let Python handle them (Which it did, by crashing our program). However, sometimes we want to ‘catch’ these exceptions instead of letting them reach Python. We can do this by using a try except block.

try:
raise Exception
print('I'm safe')
except Exception:
print('Caught ya!')
# Console output:
#
# Caught ya!

From this, we can see that code is run within the try block. If any code within the block raises Exception, it will stop executing the try block and instead run the code in the except block. It is important to note that the except block only catches errors specified to it’s right.

try:
a_dict = {'hello': 'world'}
a_dict['doesn't exist']
except ValueError:
print('This won't be called')
# Console output:
#
# KeyError: 'doesnt exist'

The except block catches any exception that is raised within the try block. This is true even if the exception is raised within a function that is called in the try block.

def raise_exception:
raise Exception
try:
raise_exception()
print('I\'m safe')
except Exception:
print('Caught ya!')
# Console output:
#
# Caught ya!

Besides the try and except clauses, there is also the else clause. The else clause runs if no exceptions are caught within the try clause.

try:
print('I\'m Safe')
except Exception:
print('This will not happen')
else:
print('No exceptions happened')
# Console output:
#
# I'm Safe
# No exceptions happened

There is also the finally clause. This code will be run after the 3 clauses above, no matter what occurs.

try:
raise Exception
print('I\'m Safe')
except Exception:
print('This will not happen')
else:
print('No exceptions happened')
finally:
print('Finally print this')
# Console output:
#
# Exception caught
# Finally print this

Custom exceptions

Sometimes, just customizing the exceptions is not enough. In order to have more customizability, you can subclass any of the existing Exception classes.

class MyCustomException(Exception):
""" Whatever this exception is for """

This works just like how subclassing works in Python; You can override the constructors to provide extra functionality to your Exception subclass.

Conclusion

After reading this, you should be equipped with all the knowledge you need to use exceptions within your code to your advantage.

A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.