In this article, you will learn about Python exception handling. You will learn in detail about the errors in Python, types of exceptions and the mechanism to handle the exceptions raised.
An exception simply is an error that occurs during the execution of a program.
When the Python program encounters a situation that disrupts the flow of the program, it raises an exception that can be handled.
If not handled properly, the interpreter throws a traceback error along with the statements that caused that error. These exceptions prevent the program from crashing.
Here is a simple example of ZeroDivisionError
.
When we write a program, there might be some possible errors that can happen down the line. If there is no backup mechanism to handle these errors, the program will simply crash.
So, Python exception handling is a mechanism in which we define a backup plan for a possible error situation.
There are two types of exceptions in Python.
Built-in exceptions are the standard exceptions defined in Python. These exceptions are raised when the program encounters an illegal operation like semantic errors.
These built-in exceptions are generated either by the interpreter or the built-in functions of Python. The interpreter returns a string indicating the error code and the related information whenever an exception is raised.
Here is the tabulated list of some of the exceptions.
Python built-in exceptions and their causes |
---|
AssertionError Raised in case of assertion statement failure. |
AttributeError Raised in case of attribute assignment failure. |
EOFError Raised when there is no input from either the raw_input() or input() function and the end of file is reached. |
FloatingPointError Raised when a floating point operation fails. |
GeneratorExit If a generator’s close() method gets called. |
IOError Raised if an input/output operation fails. |
ImportError Raised when the imported module is not available or found. |
IndentationError Raised when interpreter encounters incorrect indentation. |
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 interrupt key (Ctrl+c or delete). |
MemoryError Raised if an operation runs out of memory. |
NameError Raised when an identifier is not found in local or global scope. |
NotImplementedError Raised when an abstract method that needs to be implemented is not actually implemented. |
OSError Raised when system operation causes the system related error. |
OverflowError Raised when the result of an arithmetic operation exceeds the range. |
ReferenceError Raised when a weak reference proxy accesses a garbage collected reference. |
RuntimeError Raised when an error generated does not fall under any other category. |
StopIteration Raised when the next() method of an iterator does not point to any object. |
SyntaxError Raised when a syntactical error is encountered. |
SystemError Raised when interpreter detects an internal error. |
SystemExit Raised by sys.exit() function. |
TabError Raised by inconsistent tabs and spaces. |
TypeError Raised when a function is using an object of the incorrect type. |
UnboundLocalError Raised when trying to access a local variable in a function or method but no value has been assigned to it. |
UnicodeError Raised when a Unicode-related encoding or decoding error occurs. |
UnicodeEncodeError Raised when a Unicode-related error occurs during encoding. |
UnicodeDecodeError Raised when a Unicode-related error occurs during decoding. |
UnicodeTranslateError Raised when a Unicode-related error occurs during translating. |
ValueError Raised when a function receives invalid values. |
ZeroDivisionError Raised If the second operand of division or modulo operation is zero. |
So, these are some of the built-in exceptions in Python. These all are derived from a base exception class. Every exception is derived from a base exception class. We will learn about creating custom exceptions later in this article.
Let’s learn about how exceptions are actually handled in Python.
Exceptions are handled in Python using try
statement where suspicious codes that may raise exceptions are placed inside the try
block and the code that handle the raised exception is placed inside except block.
Here is the structure of try
and except
statement in Python.
try:
** Operational/Suspicious Code
except SomeException:
** Code to handle the exception
The try and except statements work as following.
try
block are executed to check whether or not exception occursexcept
block (except
block contains statements to handle exceptions) is skipped after the execution of try
block'SomeException'
to handle in except
block, it is handled and the program continues.except
block, the program execution stops with the corresponding error message.Defining except clause is not the better approach for any programming because such try-except
clause can handle all types of exceptions and users won’t be able to exactly identify the exception raised.
Syntax
try:
#do your operations
except:
#If there is any exception raised, execute these statements
else:
#If there is no exception, execute these statements
Here is a simple example to catch an exception if a file we try to read doesn’t exist.
try:
fp = open('example.txt', r)
except:
print ('File is not found')
fp.close
Here in this example, we have opened the file 'example.txt'
. If the file is not found it will execute code in except
block and 'File is not found'
will be printed.
A try
statement can have multiple clauses to specify handlers of different exception. In above example, we have not defined any particular exception which is not considered good programming practice.
We can define multiple exceptions with the same except
clause. Later during execution, if interpreter finds a matching exception, then it’ll execute the code written under the except
clause.
We can use a tuple to specify multiple exceptions in an except
clause. Here is an example showing how multiple exceptions are defined.
try:
# do something
except (Exception1, Exception2, ..., ExceptionN):
# handle multiple exceptions
pass
except:
# handle all other exceptions
Beside try
and except
blocks, we can also use try
and finally
blocks together.
The finally
block contains statements that must be executed whether or not the exception is caught and raised in the try
block.
This is useful to release external resources and clear up the memories.
Here is the pseudo code for try..finally
clause.
try:
# perform operations
finally:
#These statements must be executed
try:
fp = open("example.txt",'r')
#file operations
finally:
fp.close()
This will ensure that file is closed after all the operations are done with.
As the name goes by the exceptions defined by a user are called User-Defined Exceptions.
Sometimes in a program, we need create custom exceptions to serve our own purposes. Python also allows us to create our own exceptions by deriving classes from the standard built-in exceptions.
We can create user-defined exceptions by creating a new class in Python. Directly or indirectly the custom exception class has to be derived from the base exception class. Most of the built-in exceptions are derived from this base class to enforce their exceptions.
>>> class UserDefinedError(Exception):
... pass
>>> raise UserDefinedError
Traceback (most recent call last):
...
__main__.UserDefinedError
>>> raise CustomError("An error occurred")
Traceback (most recent call last):
...
__main__.UserDefinedError: An error occurred
As you can see in above example, we have created a user-defined exception class, the “UserDefinedError“ which is derived from the base Exception class as the parent. This user-defined exception class can raise exceptions as any other exception class by simply calling the “raise” statement with an optional error message.
We can define these user-defined class as our requirement and it’s better to place all these exceptions in a separate file for the ease.
Let’s create a user-defined exception where the program will ask the user to input a number again and again until the user enters the correct stored number.
Here we will demonstrate how to raise an user-defined exception and catch errors in a program.
#User-defined exceptions
class Error(Exception):
"""Base class for other exceptions"""
pass
#Define class for NegativeValueError
class NegativeValueError(Error):
"""Raised when the input is negative"""
pass
#Define class for ValueTooSmallError
class ValueTooSmallError(Error):
"""Raised when the value is too small"""
pass
#Define class for ValueTooLargeError
class ValueTooLargeError(Error):
"""Raised when the value is too large"""
pass
#main program
#Takes input till the user inputs correct value
#Stored number
number = 11
while True:
try:
num = int(input("Enter a number: "))
if num < 0:
raise NegativeValueError
elif num < number:
raise ValueTooSmallError
elif num > number:
raise ValueTooLargeError
break
except NegativeValueError:
print("This is a negative value, try again")
print("")
except ValueTooSmallError:
print("This value is too small, try again")
print("")
except ValueTooLargeError:
print("This value is too large, try again!")
print("")
print("Correct value entered")
Here in this program, we have defined a base class Error from which three other exceptions NegativeValueError
, ValueTooSmallError
and ValueTooLargeError
are derived.
Let’s try this program with multiple test values.