Home

 › 

Articles

 › 

Understanding Exception Handling in Python, With Examples

Switch Case Python

Understanding Exception Handling in Python, With Examples

Key Points

  • Exception handling in Python is necessary to account for possible issues that may occur during the execution of software or applications.
  • There are three types of errors in Python: syntax errors, exceptions (or runtime errors), and logical errors.
  • Some commonly used built-in exceptions in Python include AttributeErrors, NameErrors, TypeErrors, and IndexErrors.
  • In addition to built-in exceptions, Python allows for the creation of custom exceptions to handle specific scenarios.
  • Understanding exception handling is crucial for creating reliable and user-friendly software applications.

In a perfect world, all our code would work flawlessly without any need to consider what might go wrong when we put our code into production. However, we don’t live in a perfect world. As you can imagine, there are more than a few things that could go wrong during the execution of your software or application:

  • A user enters the wrong type of information (maybe a string where an integer was expected)
  • Usernames and/or passwords are incorrect
  • The application failed to connect to the database
  • Some device has failed to connect
  • User has lost connection to the network or Internet
  • Resources (files, database tables, etc.) are unavailable
  • There is a memory conflict
  • And much, much more

This doesn’t always mean there is something wrong with your code. But you will need to account for these possible issues in your code by using exceptions. If you’re new to coding with Python, you might not have had much of a chance to work with exceptions.

If that’s the case, have no fear. We’re going to dive into exception handling in Python and work our way through a few simple examples. Let’s get into it!

Exception Handling in Python: Errors vs. Exceptions

Before we dive into learning about exceptions, we need to clear something up: there is one distinct difference between an error and an exception.

You will encounter errors while coding that will prevent your software from running properly due to an issue in the syntax of your code. Meanwhile, an exception occurs during runtime.

Software developers on all levels experience errors in Python when they’re testing their code. Don’t feel bad. It is just part of the game. How you handle them is what matters.

There are three types of errors you will occasionally experience as you write your programs. Let’s look at them one by one.

Syntax Errors

This type of error occurs when the Python interpreter doesn’t understand your code. Put simply, this means you didn’t follow the syntax rules for the programming language.

For instance, if you’re printing a simple string, you might forget to put quotes around the string inside the parenthesis. You’ll receive a syntax error and will have to fix your code before it will run.

Exceptions (or Runtime Errors)

An exception occurs when something unexpected happens while your application is running. In this scenario, your syntax might be absolutely perfect, but you either misspelled something that you defined, or you encountered something unexpected once your code ran.

Logical Errors

This type of error is challenging to identify because the program will run without any error messages or exception warnings. However, it will give you incorrect results when your program runs.

This is likely due to incorrect logic written in your code. One of the ways to avoid this is to test each section of code as you go along and ensure you don’t move on until it produces the right results.

Types of Built-In Exception Handling in Python

A built-in exception is a form of runtime error built into the programming language. We don’t have enough space here to go over every single built-in exception in Python, but we will briefly discuss the most commonly used exceptions and show examples of them in code.

1. AttributeErrors

Put simply, an attribute is a variable of a class that belongs to all instances of that class. If all the appropriate attributes are used throughout your code, then you won’t have a chance to see how this works.

However, at some point, you will either misspell an attribute or forget to put a specific attribute in your class, so you’ll need to handle these possibilities in your code. See the example below.

example of exception handling in python
An example of exception handling in Python, showing the AttributeError exception.

©History-Computer.com

In this short code snippet, we’ve created an “Animal” class that has three attributes: name, age, and species. In our main code, we’ve instantiated “newAnimal,” which sends the expected parameters to the class.

Below that, we’ve created what’s called a try/except block. In the “try” portion of the block, we’re telling Python to try to execute the code within its scope.

In this block, if the code doesn’t execute successfully, Python gives control to the “except,” block, which in this example is the error message that describes exactly what went wrong. If you run this code, and the attribute isn’t typed out exactly as it is in the program, it will throw this AttributeError.

2. NameErrors

This type of built-in exception is similar to Python’s AttributeError; however, it has one slight difference. NameErrors indicate that we’re trying to access a variable or function that doesn’t exist in the current scope.

See below for an example, along with the output:

exampe two of exception handling in python
Trying to call a variable or function that does not exist is a common mistake.

©History-Computer.com

exampe two of exception handling in python output
Doing so will lead to a NameError, and Python will alert you that the variable or function is not defined.

©History-Computer.com

The code at the top is a simple function that returns the average of two numbers by dividing their sum by 2. However, you can clearly see below in the main area of our code that the call to the function is incorrect.

Since there was nothing wrong with our syntax, the compiler tried to execute the code, but it ran into a NameError because there was a mismatch between the function definition and the call to the function.

Something this simple is hard to miss when coding because you can clearly see the red underline that indicates our code is problematic. The IDE used here is PyCharm; however, any other IDE you use should behave similarly.

3. TypeErrors

This is another common exception many beginning and experienced Python developers see. It simply means Python is expecting a type that it didn’t receive.

For instance, maybe it was expecting a float value (or variable), and you coded with a string. It sounds inconceivable that this might happen, but you’ll see in the example below that it’s not hard at all to make this mistake!

TypeError exceptions in Python
TypeError exceptions are handy for alerting you when you use an incorrect type.

©History-Computer.com

In this short program, we’re asking for input from the user of two numbers so we can do a simple calculation. However, there’s an issue if you don’t account for how Python stores input data.

You see, anything the user enters goes into memory as a string. So, if you need it in integer form, you have to cast it as an integer.

We’ve done this appropriately in the first line of the “try” block. But, in the second line, we’ve let it stay as a string to demonstrate what happens when you try to do calculations with a number stored as a string.

Since the “y” variable was stored as a string, the “try” block will give control over to the except block because it detected a TypeError exception. And you should remember that any other sort of exception would result in an error message in the terminal since it wasn’t handled within the code.

So, if we had gotten a NameError exception here (but not a TypeError), the “except” block wouldn’t execute, and the program would stop its execution, throwing a TypeError message in the terminal.

4. IndexErrors

Another common exception that occurs is when you’re working with a collection of data, and you try to access an element that doesn’t exist.

This will result in an IndexError exception, and we highly recommend always planning for this type of exception in your code when you’re working with data collections.

Here’s an example using a list in Python:

IndexError exceptions in Python
As soon as a number that is larger than the index is inputted, and IndexError will be raised.

©History-Computer.com

Here, we have a list at the top of five animals. We set a boolean variable to control whether the user wants to play again, then we head into the try-except block to check for any exceptions that might occur. 

If the user enters 0, 1, 2, 3, or 4 (remember: list numbering begins at 0), then one of the corresponding animals prints to the screen. However, we had to account for any numbers above that because it’s likely the user would enter bigger numbers as well.

As soon as a number bigger than 4 is entered, control goes over to the “except” block since we’ve engaged an IndexError. 

From there, we let the user know what happened, and we ask them if they want to play again. If not, we switch the boolean value to True, then the program ends.

Otherwise, we loop through another time to check for a different number. Whether the “except” block executes or not, we continue asking if they want to enter another number until they finally give up and enter “n” for no.

More Built-In Exceptions

The exceptions above are not an exhaustive list of all the possible run-time errors you’ll encounter, but they are the most common. You might also want to familiarize yourself with the following built-in exceptions:

  • ZeroDivisionError: Occurs when the program attempts to divide by zero
  • EOFError: Occurs when you hit the end of a file without reading any data
  • ImportError: Occurs when the compiler is having an issue loading a module you attempted to import
  • FileNotFoundError: Occurs when a named file or directory cannot be found
  • KeyError: Occurs when a key cannot be found in a dictionary
  • RunTimeError: Occurs when an exception does not fit in any other category

Exception Handling in Python: User-Defined Exceptions

In addition to Python’s built-in exceptions, you also have the ability to create custom exceptions. You will find this capability to be extremely useful once you start building real-world applications that need to be able to communicate well with the end user.

The hardest part with user-defined exceptions is knowing exactly what type of exceptions you’ll need for your program. This knowledge will grow as you develop more complex algorithms and gain more experience with Python.

But, with each individual program you’re working on, you’ll be able to figure out what type of exceptions to create once you do some thorough testing of how your code behaves.

Example of a User-Defined Exception

If you want to create your own exception, you’ll need to start by defining a class that inherits from the built-in Exception class. Let’s look at how to do that.

In the example code below, we’ve created a short algorithm that tests whether a user’s email and password match the information in the database.

Before you get too excited, remember that in a real-world application, this would be much more complicated, with hashing algorithms to encrypt sensitive information and more.

custom exception handling in python
Defining a class to inherit from the Exception class is the first step in creating a user-defined exception.

©History-Computer.com

The execution with this code starts at line 17, where we create the dictionary of usernames and passwords. As you can see, each respective user has a corresponding password that our algorithm will check. 

Next, we ask the user for their username and password, storing those in their own string variables. This allows us to perform the next step, where we call the “login” function that sends the username and password so we can check to see if there is a match.

In the class definition at the top of our code, we created a custom exception class, based on Python’s internal exception class. No code executes here, so we documented and used “pass” to indicate that we don’t need to do anything here.

Because we told the compiler that “InvalidLogin” is based on the “Exception” class, it knows to inherit all the elements and behavior from the original class.

Fixing the User-Defined Exception

Now, let’s look at our “login” function. It receives the username and password from the main code and checks the dictionary to see if there’s a match.

The function’s algorithm checks to see if the username exists. If it doesn’t, it raises our user-defined function, “InvalidLogin.” If it does, it moves on to check the password to make sure it’s that user’s password.

However, if both conditions pass, then the user receives a simple printed message of “Login successful,” and the program ends. Otherwise, Python raises an exception, and the user sees this message: “InvalidLogin: Invalid username or password.”

In a real-world application, you’d likely have a separate file that hosted all your exceptions to keep your main app code clean and easy to read. If that were the case here, we’d need to import the exception file at the top of the program so the compiler would know where to grab those class definitions.

Understanding Exception Handling in Python: Wrap-Up

After working through these examples and doing some testing of your own, you should now have a much better understanding of Python errors, exceptions, and how best to handle them in your code.

When it comes to creating applications meant for production, this is a concept you will need to understand backward and forward to make your software useful to a variety of users.

Just like any other type of business communication, using exceptions and exception handling will help you build a better relationship between your software product and the users who work with it daily. Now, let’s answer some commonly asked questions about exception handling in Python.

Understanding Exception Handling in Python, With Examples FAQs (Frequently Asked Questions) 

What is exception handling in Python?

Exception handling in Python involves using try and except blocks to catch and handle exceptions. Python executes code following the try statement as a normal part of the program. The code that follows the except statement is the program’s response to any exceptions in the preceding try clause.

When an error occurs during the execution of the try block, the program control is passed to the corresponding except block, preventing the program from crashing and allowing it to continue its normal execution

What is the best practice for exception handling in Python?

The best practice for exception handling in Python is to catch and handle specific exceptions rather than using a bare except clause. This is because catching all exceptions can hide errors and make debugging more difficult.

What is error handling vs exception handling in Python?

Error handling in Python refers to the process of responding to errors that occur during the execution of a program. Exception handling is a specific form of error handling that deals with exceptions, which are events that occur during the execution of a program that disrupt the normal flow of the program’s instructions.

What is the raise statement in Python?

The raise statement in Python is used to trigger or “raise” an exception whenever a specified condition is met or an error is encountered.

What is the finally clause in Python?

The finally clause in Python is an optional clause that can be added to a try/except block. It is intended to define clean-up actions that must be executed under all circumstances.

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. Its primary purpose is to let you execute code regardless of what the try and except blocks result in.

To top