A Beginner’s guide to Exceptions in Python

An exception is an error that occurs during the execution of a program. This article will discuss how to handle exceptions in Python programming with try-except blocks. This is a very important construct with many applications and will help you to make your programs more robust.

If we want to handle errors gracefully in our Python programs, we can use a special block of code known as a try-except block. First we try to run some code in the try part of the block, and if an exception occurs, control is transferred to the except part of the try-except block.

Try-Except Block Example in Python

Here’s what a generic try-except block looks like in Python:

try:
    # Code that may raise an exception goes here
    pass
except ExceptionType:
    # Code to handle the exception goes here
    pass

As you can see, the try section contains the code that may raise an exception, and the except section contains the code that will be executed if an exception is raised.

Surprisingly, this code actually runs without an error, even though we have used the extremely generic ExceptionType for the except part of the try-except block. Not a very interesting program though. We will look at more useful examples next.

Handling Index Errors in Python

Now that we have a basic understanding of what an exception is and how try-except blocks work, let’s look at a more useful example: catching index errors in Python and handling them gracefully (i.e. without your program crashing).

This example shows how to use try and except to deal with when an index value error occurs.

import random

xs = [random.randint(0, 9) for _ in range(10)]

for i in range(len(xs)):
    try:
        print(xs[i] == xs[i + 1])
    except IndexError:
        print("That index doesn't exist.")

Here’s an example of output from that code:

True
False
False
False
False
False
False
False
False
That index doesn't exist.
>>>

So what’s happening in the above example?

We created a list of random numbers and displayed True or False depending on whether each value was the same as the next in the list. However, we were not careful about the indices we used, so we ended up testing a value at a non-existent index. However, rather than the program crashing, we anticipated the problem and provided a helpful user message instead.

Now we could have been more careful with out indices and it’s usually a good idea to anticipate these kinds of problems. However, there are some cases where the Pythonic wisdom of “EAFP, or easier to ask forgiveness than permission*” is the way to go, and for these cases, try-except blocks are your friend.

  • Sometimes!! There are some very notable exceptions to this in life outside programming.

Handling Division By Zero Errors in Python with ZeroDivisionError

Here’s another example of how you can anticpate a certain type of error and handle it gracefully in Python:

def find_mean(numbers):
    try:
        return sum(numbers) / len(numbers)
    except ZeroDivisionError:
        return 0

In this code, we define a function called find_mean that takes a list of numbers as input. Inside the function, we use a try-except block to catch any ZeroDivisionError exceptions that may be raised when we try to divide the sum of the numbers by the length of the list. If a ZeroDivisionError is raised, we return 0 from the function.

Raising Exceptions in Python

Sometimes we may want to intentionally raise an exception in out program, and then handle it appropriately. To raise an exception in Python, you use the raise keyword. One common exception you may wish to raise is raise SystemExit which exits your program cleanly. Raising exceptions allows us to deliberately generate the behaviour that would occur if the exception were raised by a program. For example:

raise Exception("This is an exception")

In this example, we’re raising an exception of type “Exception” with the message “This is an exception”. You can raise any type of exception you want. Some of the most important built-in exceptions in Python programming along with the errors that cause them are listed below:

Exception Cause of Error
AssertionError Raised when an assert statement fails.
EOFError Raised when the input() function hits end-of-file condition.
ImportError Raised when the imported module is not found.
IndexError Raised when the index of a sequence is out of range.
KeyError Raised when a key is not found in a dictionary.
KeyboardInterrupt Raised when the user hits the interrupt key (Ctrl+C or Delete).
NameError Raised when a variable is not found in local or global scope.
OSError Raised when system operation causes system related error.
StopIteration Raised by next() function to indicate that there is no further item to be returned by iterator.
SyntaxError Raised by parser when syntax error is encountered.
IndentationError Raised when there is incorrect indentation.
SystemExit Raised by sys.exit() function.
TypeError Raised when a function or operation is applied to an object of incorrect type.
ValueError Raised when a function gets an argument of correct type but improper value.
ZeroDivisionError Raised when the second operand of division or modulo operation is zero.

User-defined Exceptions in Python

In Python, you can define your own exceptions by creating a class that inherits from the built-in Exception class. For example:

class MyCustomError(Exception):
    pass

You can then raise this exception using the raise keyword, like this:

raise MyCustomError("An error occurred")

You can also define your own exception class with additional attributes that can be used to store more information about the error. For example:

class MyCustomError(Exception):
    def __init__(self, message, errors):
        # Call the base class constructor with the parameters it needs
        super().__init__(message)
        # Now for your custom code...
        self.errors = errors

You can then raise this exception and access the additional attributes like this:

try:
    raise MyCustomError("An error occurred", [1, 2, 3])
except MyCustomError as e:
    print(e.errors)

This would output [1, 2, 3].

There are many situations where having your own exception class is helpful, and using the above technique gives you fine control of how your program will respond to various types of error, as defined by you.


This article has discussed how to work with exceptions in Python using try-except blocks. This can be useful for handling potential errors in your code and ensuring that your programs run smoothly.

Sharing is caring!

Leave a Reply

Your email address will not be published. Required fields are marked *