Startertutorials Blog
Tutorials and articles related to programming, computer science, technology and others.
Subscribe to Startertutorials.com's YouTube channel for different tutorial and lecture videos.

Categories: Python Programming. No Comments on Exception Handling in Python

This article provides a comprehensive overview of exception handling in Python programming language along with example programs.

 

Introduction

An error is an abnormal condition that results in unexpected behavior of a program. Common kinds of errors are syntax errors and logical errors. Syntax errors arise due to poor understanding of the language. Logical errors arise due to poor understanding of the problem and its solution.

 

Anomalies that occur at runtime are known as exceptions. Exceptions are of two types: synchronous exceptions and asynchronous exceptions. Synchronous exceptions are caused due to mistakes in the logic of the program and can be controlled. Asynchronous exceptions are caused due to hardware failure or operating system level failures and cannot be controlled.

 

Examples of synchronous exceptions are: divide by zero, array index out of bounds, etc.) . Examples of asynchronous exceptions are: out of memory error, memory overflow, memory underflow, disk failure, etc. Overview of errors and exceptions in Python is as follows:

 

types-of-errors

 

Handling Exceptions

 

Flowchart for exception handling process is as follows:

 

exception-handling-flowchart

 

We can handle exceptions in Python code using try and except blocks. Statements which can raise exceptions are placed in try block. Code that handles the exception is placed in except block. The code that handles an exception is known as exception handler and this process is known as exception handling.

 

try and except

 

Syntax for using try and except for exception handling is as follows:

 

try:
	statement(s)
except  ExceptionName:
	statement(s)

 

Following is an example for handling divide by zero exception using try and except blocks:

 

numerator = int(input())
denominator = int(input())
try:
	quotient = numerator / denominator
	print("Quotient:", quotient)
except  ZeroDivisionError:
	print("Denominator cannot be zero") 

Input:
10
0

Output:
Denominator cannot be zero 
Input:
10
2

Output:
Quotient: 5.0

 

Multiple Except Blocks

 

Often, there will be a need to handle more than one exception raised by a try block. To handle multiple exceptions, we can write multiple except blocks as shown below:

 

try:
	statement(s)
except  ExceptionName1:
	statement(s)
except  ExceptionName2:
	statement(s)
...

 

Following is an example for handling multiple exceptions using multiple except blocks:

 

numerator = int(input())
denominator = int(input())
try:
	quotient = numerator / denominator
	print("Quotient:", quotient)
except  NameError:
	print("You are using a variable which is not declared")
except  ValueError:
	print("Invalid value")
except  ZeroDivisionError:
	print("Denominator cannot be zero")

 

In the previous example for input 10 and 0, the output displayed is “Denominator cannot be zero”. When the divide by zero exception was triggered in try block, first two except blocks were skipped as the type of exception didn’t match with either NameError or ValueError. So, third except block was executed.

 

Multiple Exceptions in a Single Block

 

We can handle multiple exceptions using a single except block as follows:

 

try:
	statement(s)
except(ExceptionName1, ExceptionName2,..):
	statement(s)

 

Following is an example which demonstrates handling multiple exceptions using a single except block:

 

numerator = int(input())
denominator = int(input())
try:
	quotient = numerator / denominator
	print("Quotient:", quotient)
except (NameError,ValueError,ZeroDivisionError):
	print("Denominator cannot be zero") 

For input 20 and 0, the output for the above code is:

Denominator cannot be zero

 

Handle Any Exception

 

In some cases, we might want to execute the same code (handler) for any type of exception. Such common handler can be created using except as follows:

 

try:
	statement(s)
except:
	statement(s)

 

Following is an example which demonstrates handling any exception with a single except block:

 

numerator = int(input())
denominator = int(input())
try:
	quotient = numerator / denominator
	print("Quotient:", quotient)
except:
	print("Denominator cannot be zero") 

For input 8 and 0, the output for the above code is:

Denominator cannot be zero

 

else Clause

 

The try and except blocks can be followed by an optional else block. The code in else block executes only when there is no exception in the try block. The else block can be used to execute housekeeping code like code to free the resources that are being used.

 

Raising Exceptions

 

We can raise exceptions manually even though there are no exceptions using the raise keyword. Syntax of raise statement is as follows:

 

raise[ExceptionName [, args [, traceback]]]

 

ExceptionName is the type of exception we want to raise. Args are the exception arguments and traceback is the traceback object used for the exception. Following is an example for demonstrating raise keyword:

 

try:
	raise NameError
except  NameError:
	print("Name error")

 

In the above code NameError exception is raised by the raise statement and is handled by the except block.

 

Re-raising Exceptions

 

In Python, we can re-raise the exceptions in the except block by writing raise keyword. Following code demonstrates re-raising exceptions:

 

try:
	raise  NameError 
except  NameError:
	print("Name error")
	raise 

Output is as follows:

Name error
Traceback (most recent call last):
  File "test1.py", line 2, in <module>
    raise NameError 
NameError

 

Handling Exceptions in Functions

 

We can use try and except blocks inside functions as we are using until now. In the try block, we can call a function. If this function raises an exception, it can be handled by the except block which follows the try block. Following example demonstrates handling exceptions in functions:

 

def  div(num, denom):
	return num/denom 
try:
	div(30, 0)
except  ZeroDivisionError:
	print("Denominator cannot be zero") 

Output for the above program is as follows:

Denominator cannot be zero

 

finally block

 

A try block must be followed by one or more except blocks or one finally block. A finally block contains code that executes irrespective of whether an exception occurs or not. Syntax for finally block is as follows:

 

try:
	statement(s)
finally:
	statement(s)

 

The finally block is generally used to write resource freeing code. We cannot write a else block along with finally block.

 

Built-in Exceptions

 

There are several built-in or pre-defined exceptions in Python. Python automatically recognizes the built-in exceptions and handles them appropriately. Following are some of the built-in exceptions in Python:

 

Exception Description
Exception Base class for all exceptions
StandardError Base class for all built-in exceptions (excluding StopIteration and SystemExit)
SystemExit Raised by sys.exit() function
ArithmeticError Base class for errors generated by mathematical calculations
OverflowError Raised when the maximum limit of a numeric type exceeds
FloatingPointError Raised when a floating point error could not be raised
ZeroDivisionError Raised when a number is divided by zero
AssertionError Raised when the assert statement fails
AttributeError Raised when attribute reference or assignment fails
EOFError Raised when end-of-file is reached or there is no input for input() function
ImportError Raised when an import statement fails
LookupError Base class for all lookup errors
IndexError Raised when an index is not found in a sequence
KeyError Raised when a key is not found in the dictionary
NameError Raised when an identifier is not found in local or global namespace
IOError Raised when input or output operation fails
SyntaxError Raised when there is syntax error in the program
ValueError Raised when the value of an argument is invalid
RuntimeError Raised when the generated error does not fall into any of the above categories
NotImplementedError Raised when an abstract method that needs to be implemented is not implemented in the derived class
TypeError Raised when two incompatible types are used in an operation

 

 

User-defined Exceptions

 

If the pre-defined exceptions doesn’t handle your custom error condition, we can create our own exceptions. Such exceptions are known as user-defined or custom exceptions. Steps in creating custom exceptions:

 

  1. Create a new class and extend Exception class.
  2. Raise the custom exception.
  3. Handle the custom exception.

 

Following example demonstrates creating and using a user-defined exception:

#NegativeError is the custom exception
class  NegativeError(Exception):
	def  __init__(self, value):
		self.value = value
	def  __str__(self):
		return repr(self.value)
try:
	raise  NegativeError(-20)
except  NegativeError  as  ne:
	print(ne.value,"is negative.")

 

How useful was this post?

Click on a star to rate it!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Suryateja Pericherla

Suryateja Pericherla, at present is a Research Scholar (full-time Ph.D.) in the Dept. of Computer Science & Systems Engineering at Andhra University, Visakhapatnam. Previously worked as an Associate Professor in the Dept. of CSE at Vishnu Institute of Technology, India.

He has 11+ years of teaching experience and is an individual researcher whose research interests are Cloud Computing, Internet of Things, Computer Security, Network Security and Blockchain.

He is a member of professional societies like IEEE, ACM, CSI and ISCA. He published several research papers which are indexed by SCIE, WoS, Scopus, Springer and others.

Leave a Reply

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