Exception handling in python is very similar to C++ and Java.
The following table lists how Java and Python support exceptions.
Java
Python
try
{
throw new Exception ("some message");
} catch (Exception e)
{
System.out.println (e.toString());
} finally
{
// do some clean-up activity here
}
try:
raise Exception ("some message");
except Exception as e:
print (type(e))
print (e.args)
print (e)
else:
# executed if no exception is raised in the try block
finally:
# do some clean-up activity here
Example: The below function will raise an error when it attempts to divide by zero.
def func(a,b):
try:
c = a/b
except Exception as e:
print (type(e))
print (e.args)
print (e)
else:
print ('Able to divide')
return c
finally:
print ('Finally block executes')
func (18, 6)
# Output:
# Able to divide
# Finally block executes
# 3.0
func (18, 0)
# Output:
# <class 'ZeroDivisionError'>
# ('division by zero',)
# division by zero
# Finally block executes
Note: The copy paste from the above may remove the indentation spaces due to which python can give indentation errors.
If such a thing happens, then indentation spaces have to be put manually after copy-paste.
An interesting observation in the above example is that the finally block executes even when there is no exception.
Also, the finally block executes even when there is a return statement in the else block.
This confirms the statement that the finally block always executes whether or not there is an exception.
Hence, finally is a good place to close file handles, free system resources etc.
Custom exception classes
It is possible to write one's own Exception classes just like any other classes.
But to make it behave like an Exception, it should be derived (directly or indirectly) from the class Exception.
# Directly derived from Exception
class FooException (Exception):
def __str__ (self):
return "FooException occured"
# Indirectly derived from Exception (via FooException)
class BarException (FooException):
def __init__ (self, c):
self.c = c
def __str__ (self):
return "FooException occured with c=" + self.c
raise FooException('AAA', 'BBB')
# Output:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# __main__.FooException: FooException occured
raise BarException('CCC')
# Output:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# __main__.BarException: FooException occured with c=CCC
Automatic clean-up using 'with'
Actions to be performed in most of the finally clauses are
closing files, freeing up string buffers etc.
Some of these actions are so routinely done in finally clauses that
Python encapsulated them within a clause of its own such that whenever
a block was about to be exited, those actions would occur on their own.
with open('output.txt', 'w') as f:
f.write('Hi there!')
The above block automatically closes the file 'f' regardless of the success of f.write operation.
The with clause can be more customized by defining the auto-cleaner yourself.
For example, the following SimpleCounter is wrapped inside an AutoCleanerExample object.
Although, this AutoCleaner only increments the counter, this serves
as a good example to show that cleanup operations can be performed in the __exit__ function.
# define a simple wrapper class to hold an integer counter
class SimpleCounter:
count = 0
def __str__(self):
return str(self.count)
# The class to be used by 'with' clause
class AutoCleanExmple():
def __init__(self, obj):
self.obj = obj
def __enter__(self):
self.obj.count += 1
return self.obj
def __exit__(self, type, value, traceback):
self.obj.count += 2
# Using the simple counter and its auto-cleaner
obj = SimpleCounter()
for i in range(6):
print ("Beginning with " + str(obj))
with AutoCleanExmple(obj):
print (obj)
Output:
Beginning with 0
1
Beginning with 3
4
Beginning with 6
7
Beginning with 9
10
Beginning with 12
13
Beginning with 15
16
Got a thought to share or found a bug in the code? We'd love to hear from you: