In this tutorial you will learn all about exceptions in Python – the different types of errors and exceptions and how to handle them.
There are three kinds of errors in Python: syntax errors, exceptions (runtime errors) and logical errors.
What is Syntax?
Syntax: a set of rules we must follow that define the correct structure of the code.
Errors caused by incorrect use of the Python language are called syntax errors or parsing errors. You can think about these errors as spelling or grammar mistakes in a language. Python will find syntax errors when it tries to parse the program. Since the code can’t be parsed, Python exit without running anything. If a syntax error occurs, Python tries to tell where the error is located. Watch the example:
#Syntax errors for i in range(5) print('a')
In the example above the colon is missing and therefore it is a syntax error. If you run the code the program will raise an error.
Exceptions (Runtime Errors)
Errors caused by syntactically correct Python code are called exceptions or runtime errors. During the execution of a program with an exception, the interpreter stops executing the program and displays an error message when the exception is occurred.
In addition, Python prints a traceback that can help you find what causes the error. Watch the example below:
#Exceptions my_list = [1, 2, 3] print(my_list)
In the exapmle above we try to get and index that is out of range resulting an IndexError.
Logical errors cause the program to run incorrectly – resulting incorrect or unexpected results. Logical errors don’t raise error messages, because no syntax or runtime errors have occurred. These errors are most difficult to fix, since they don’t cause the program to crash, and no errors are raised.
For instance, using a wrong algorithm for a certain problem. This kind of error might not case the program to crash. However, it will most definitely return wrong results.
It is very naïve approach to code a program without thinking about things that can go wrong. Python has a set of tools that can help us handling exceptions if needed. In the next topics you will learn all about handling exception in Python.
A traceback is a report containing the function calls made in your code. Python prints a traceback whenever an unhandled exception occurs. The traceback tells which line in the code has caused the exception. Moreover, it tells what type of error causes the program to crash. Watch the example:
Reading the traceback might be overwhelming at first. However, it is an important skill for a Python programmer, and like anything else with practice it becomes second nature.
What is an Exception in Python
By now you have probably heard that everything in Python is an object. So, you won’t be surprised to find out that the exceptions python raises are also objects. Python raises an exception when an event that disrupts the normal flow of program occurs. There are different types of errors that can cause the program to crash, therefore there are different types of exception objects. For instance, a crash caused by incorrect use of types (TypeError) is different than a crash caused by using an undefined variable (NameError).
Python has a set of built-in exceptions. All of them are instances of a class that derives from the Exception class. The programmer can also create new exceptions.
How to Define Custom Exceptions in Python
In Python we can define custom exceptions classes. It is great because the built-in exceptions are limited and there might be some cases that require creating new and unique exceptions. Any exception object in Python should be derived from the Exception class or one of its subclasses (the built-in exceptions). Please notice that deriving exceptions from BaseException class is considered to be bad practice as it can lead to unexpected results. Watch the example:
#Custom Exception class SomeError(Exception): pass error = SomeError('Nice to know') raise error
The raise Statement
Using the raise statement, you can cause the program to raise exception at runtime. This will cause the program to exit and to print a traceback. Please notice – it is best to use the built-in exceptions. However, if needed don’t hesitate to define custom exceptions. Here is an example:
Lets say that the program’s input must be an integer between one to four. What happens if the user enters a different number? The best approach is to raise an exception.
#Raise def foo(number): if number > 4: raise Exception("The input is not valid") print(number) foo(3) foo(5)
Python try and except
try and except Statement
Using the try and except statement we can catch exceptions and handle them. It is an important tool that can help us handling errors, thus preventing the program to crash. Python tries to run the code under the try statement. If an exception is raised, the program will stop at the line that caused the error and the code under the except statement will run.
#try and except try: print(1/0) except: print("A number can't be dvided by 0")
How to Catch Specific Exceptions in Python
In the example above the except clause catches any exception. Sometimes we would like to handle different kinds of exceptions in different ways. The way to do it is by specifying which exception the except clause should catch. It is possible to use multiple exception clauses after a try. Notice that only one exception will be executed, and it will be the first one that cached the specific exception that occurred.
#Catching a specific exception try: print(1/0) except TypeError: print("This is a TypeError") except ZeroDivisionError: print("A number can't be dvided by 0")
How to Catch Multiple Exceptions in one Except Clause
It is possible to catch any number of exceptions in one except clause. It is done by using a tuple to specify multiple exceptions. In some cases, we would like to handle multiple exceptions the same way and this is the way to do it.
#Catching Multiple Exceptions try: print(1/0) except (ZeroDivisionError, TypeError): print("This is a TypeError or a ZeroDivisionError")
Python try except and else
The else statement is an optional one, and it allows to run code only if the code block inside try ran without raising any exceptions. If an exception occurs, the code under the else statement won’t be executed. When present, the else clause must follow all except clauses. In most cases it is better to prefer the use of else clause over adding the code to the try clause. It avoids unexpected behavior. Watch the example:
# try except and else try: print("Hey!") except: print("Catching an exception") else: print("Something else") try: print(1/0) except: print("Catching an exception") else: print("Something else 2.0")
Python try except else and finally
The finally statement is an optional one. The code under the finally statement is executed no matter what – whether or not and exception was raised. When present, the finally clause must follow all other clauses (try, except, else) and it will be the last task before the try statement is completed. Watch the example:
# try except else and finally try: print(1/0) except (ZeroDivisionError, TypeError): print("This is a TypeError or a ZeroDivisionError") else: print("There is an error. It won't be printed") finally: print("The finally statement is executed")
Python Exceptions Handling Summery
- The try clause is executed. If an error occurs it exits and continues to the next clause.
- The except clause is executed if an error occurs. You can limit the except to specific errors. If the except is defined to handle the current exception, the clause is executed. Otherwise, it continues to the next cluse.
- The else clause is executed if and only if the code block inside try ran without any errors.
- The finally clause is executed regardless of the result of the try and except clauses.
Python Exception Handling Flow Chart