Python Decorators Basics

Adding parameters to decorators

In the previous page we simplified our code by using a decorator to handle exceptions keeping clear the implementation of a function. This is a great improvement over repeating the same code over and over for each function we write but someone might make the case that this solution is very generic and we might need more control over the implementation of the decorator to specify its behaviour.

This can be accomplished by a decorator with parameters which is slightly more complicated than a parameter-less one and it can be done by nesting our current decorator within a higher level function which will now become the real decorator.

Continuing our example, let’s assume that we can solve our problem by using a boolean called that will either make our handler to print the message or not. Based on this our decorator should now look like this:

def handle_exceptions(foo):
def inner(*args, **kargs):
try:
foo(*args, **kargs)
except Exception as ex:
if print_message:
print ex
return inner
return handle_exceptions

The question now is, how we can pass the print_message boolean that is used in the exception handler. Very easy! We just wrap our function within a higher level function which takes a single parameter print_message and now this new function becomes our decorator. This can be seen in the following snippet:

def handle_exceptions_ex(print_message):
def handle_exceptions(foo):
def inner(*args, **kargs):
try:
foo(*args, **kargs)
except Exception as ex:
if print_message:
print ex
return inner
return handle_exceptions

Now, the decorator part for our functions should change to the following:

@handle_exceptions_ex(True)
def print_file(filename):

and

@handle_exceptions_ex(True)
def divide(x,y):

the whole program should look like this now:

#!/usr/bin/python

def handle_exceptions_ex(print_message):
def handle_exceptions(foo):
def inner(*args, **kargs):
try:
foo(*args, **kargs)
except Exception as ex:
if print_message:
print ex
return inner
return handle_exceptions

@handle_exceptions_ex(True)
def print_file(filename):
f = open(filename)
print f.read()

@handle_exceptions_ex(True)
def divide(x,y):
a = x/y
return x / y

print_file('nonexistent_file')

In this posting we covered the basics of python decorators. There are more advanced uses of them that we will talk about in the next postings.

Leave a Reply