1. Home
  2. Docs
  3. Python 101 – Python Programming for Beginners
  4. Exception Handling in Python

Exception Handling in Python

 
You might often here like terms like Exception handling,

Error handling, Exception, Try and Catch, Handler, Throw etc.

In this section we will explore some of these.

 

What is an exception?

 
An exception is an un expected event,

which occurs during execution of program.

It disrupts the normal flow of the program.

It’s a general error situation, but not always like Ctrl+C, SysExit, StopIteration.

 

What is exception handling ?

 
Exception handling is to detect an exception at runt-time and take some action.

If the exception is not handled, the program gets terminated or halts.

Exception gives you an opportunity to do something,

When an unexpected event happen.

As programmer you need to anticipate, these events and do something when they occur.
 
With exception handling, Like you

1. can log the current state for debugging purpose.

2. show useful information to the user and gracefully exit.

3. continue with next set of program instructions.

 

What is Catch ?

 
Catch is to detect an exception and look for a handler.
 

What is Handler ?

 
A piece of code, for action to be taken, when an exception is caught.
 

What is Throw ?

 
Its mechanism to tell the interpreter to generate an exception.
 
Lets look at an error case,
 
As you know, you should not divide a number by zero

Lets take number a = 10 , and try to divide it by zero.

 
# devide a by zero

 

 a = 10


# devide a by zero
 a / 0

# this raises ZeroDivisionError  exception.

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

ZeroDivisionError: division by zero

 
In Python Exception is handling is very straight forward.

Python interpreter raises an Exception, when it detects an error at runt-time.

The most common way of handling excetion in Python is with try-except block.

 

try:

   #actual code

except:

   #handler code

 
The try block contains the statements for handling, fallowed by one more except blocks.

try block is executed till the statement,which raises an exception.

As soon as the exception is raised, the except clause which matches the exception is executed.

Let’s handle above ZeroDivisionError error.

Its very simple, just by putting the code inside the try block.
 

try:
    a/0

except:

    #Show useful message to the user

    print("Number can't be divided by zero")

 
Hanlding an exception with try statement is called catching exception.

Here the except block just prints an useful message to the user.

Actually you can do lot more, like gracefull exit, or taking program execution to different flow.

 

Along with try-exception, two more optional clauses are available.

These are , else and finally.
 
The syntax is as bellow.
 

try:

    #actual code

except:

    #handler code

else:

    #no error case code

finally:

    #finally code

 
So know we have four clauses, try, except, else, finally.

You already know how try and except works.

The finally clause will be executed at all times.

Regardless of whether an exception caught or not.
 
Example:
 
#With exception
 

a = 20

try:

    a/0

except:

    print("Can't divide by zero")

finally:

    print("Inside finally block")

output:

Can't divide by zero

Inside finally block

 
Note after try clause, exception and finally clauses are executed
 

Without Exception, notice the behaviour.

 

a = 20

try:

    a/10

except:

    print("Can't divide by zero")

finally:

    print("Inside finally block")

output:
	Inside finally block

 
Note after try clause, only finally clause is executed.

The finally clause is ideally used for resource cleanup.

We can also use else clause.

 

The else clause is executed when there is no exception is raised.
 

a = 20

try:

    a/10

except:

    print("Can't divide by zero")

else:

    print("Inside else block")

output:

	Inside else block

 
Note here after try clause, there is no exception raised, so else clause is executed.

Example showing all the four clauses.
 

Now let’s see the behaviour with exception.
 

a = 20

try:

    a/0

except:

    print("Can't divide by zero")

else:

    print("Inside else block")

finally:

    print("Inside finally block")

	
	
output:

Can't divide by zero

Inside finally block

 

Next is without exception case.
 

a = 20

try:

    a/10

except:

    print("Can't divide by zero")

else:

    print("Inside else block")

finally:

    print("Inside finally block")



output:
Inside else block

Inside finally block

 
The else block is less used in general practice.

In Python these are the common runtime exceptions

 

List of common exceptions

 
Refer exception module documentation
 

Exception Name Disctription
Exception /BaseExceptionRoot classes for most /all exception
AssertionError Failure to assert statement
SyntaxErrorPython syntax error
IndexErrorNo such index
AttributeErrorNo such attribute
KeyErrorNo such key
ZeroDivisionErrorDivision by zero
IOError input/output operation failure
ValueErrorInvalid argument given
KeyboardInterruptinterrupt from keyboard ex: ^C
TypeErrorInvalid operation for this type
NameErrorNo such object name in namespace
UnboundLocalErrorAttempted to read local var before assigning

 

The table lists most common exceptions, for list of all exception check here.
 
The above example we used a generic approach to catch all exception.

But as best practice, you should know which exception may raise by your code.

And catch only those exceptions.
 
The syntax is same with little modification.
 

try:

   #actual code

except ErrorName [as reason]:

  #handler code

 
Example:
 

a = 20

try:
    a/0

except ZeroDivisionError as e:

    print("Can't divide by zero , ", str(e))

else:

    print("Inside else block")

finally:

    print("Inside finally block")
	

​
output:

Can't divide by zero ,  division by zero

Inside finally block

 
With this we can also print the exception name.

Lets look at some more try-exception examples.
 
Ex 1:

try:
	fd = open('file.txt','r') # May Raise IOError

except IOError as e:

	print("File Open Error :", str(e))

output:

File Open Error : [Errno 2] No such file or directory: 'file.txt'

 
Here we trying to read a file which doesn’t exists.
 
An IOError exception is raised, and useful message is shown to user.
 
Ex 2:

sports = ["Football", "Golf","Cricket","Baseball"]

def get_sports(index):

    return sports[index]

try:

    i = int(input("Enter a number to get favorite sport :"))

    get_sports(i)

except IndexError as e:

    print("The sport doesnt exists :", str(e))
		

output:
	Enter a number to get favorite sport :4

	The sport doesn't exists : list index out of range	
	

 
Here we are trying to access an element outside list boundary.

Ex 3:

 

numbers_in_words = {'1':'One','10':'Ten','100':'Hundred','1000':'Thousand'}

def numbers_words(number):

    try:

        n_word = numbers_in_words[number]
        
    except KeyError as e:

        print("No mapping found for",number)
		
    else:

        print("number %s is %s " %(number, n_word))
		
    finally:

        print("Inside finally block")
 

num1 = numbers_words("1000")

num2 = numbers_words("10000")


output:

#mapping exists so else clause is executed.

number 1000 is Thousand 

Inside finally block

#mapping doesn't exist, exception clause is executed.

No mapping found for 10000

Inside finally block

 

How to raise a user defined exception ?

 
Till now we have seen the exception raised by Python Interpreter.

How about raising user defined exceptions.

Its is vary easy to raise your own exception.

Its a two step process, Lets see an example

1. You need to implement UserDefinedError class

2. then use raise statement to raise the exception.

Here let’s say you want raise UserDefinedError exception.

Implement UserDefinedError class(for more about classes, see OOP)

In this by inheritance, we are just reusing base Exception class implementation.
 

class UserDefinedError(Exception):

    pass

 
that’s it, this is your UserDefinedError class implementation.

now lets test whether a user exists in a list or not, by using raise statement.
 
Syntax:

raise <expression&gt> ("useful information to user")

 
expression is treated as class object

Example:
 

class UserDefinedError(Exception):

      pass

users = ["Alex","John","Michael","Jemy","Stuart"]

try:
    #get the user name

    u_name = input("Enter user name :")

    #check for username exists in users

    if u_name not in users:

        #raise user defined exception

        raise UserDefinedError( "User doesn't exists ")

#catch the UserDefinedError

except UserDefinedError as e:

    print("User Error :",str(e))


output:

Enter user name :Zaid

User Error : User doesn't exists 

 

This is just a basic example.

You can have more suffusticated implementation,

UnboundLocalError excetption class.

What else we can do with exceptions ?

While debugging programming,

what if you can get more information about exception occurred.

That’s really handy right?

For this you can use sys.exc_info() method from sys module.

It returns three values, exception class, exception reason, traceback object.

You can also use traceback module, to get more information about stack trace.

Trace object returned from sys.exc_info(), is used to extract, format,

and print useful information about the error.

 
Example :
 

import sys

try:

    fd = open('file.txt','r')

except IOError as e:

    print("File Open Error :", str(e))

    print(sys.exc_info())

output:

File Open Error : [Errno 2] No such file or directory: 'file.txt'

(<class 'FileNotFoundError'>, 

FileNotFoundError(2, 
'No such file or director
y'), 

<traceback object at 0x0000021C786F7088>)