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.