Michele Simionato wrote a sweet module ( called decorators )that dramatically simplifies the usage of decorators in Python.

The example below is based on one of the samples Michele provides and should help illustrate how much simpler it is to create decorators


The Scenario

Suppose you have a function called foo() that prints “Hello World” and that it’s used frequently in your codebase

def foo() :
  print “Hello World”

Imagine you are investigating some anomalous behavior and you’d like to emit some text to the console knowing when foo has been called and then when it exits. This is a very common scenario when debugging or in applications that do logging for a complex installation/configuration.


The Brute-force method without decorators

The brute-force approach is to modify foo()

def foo() :
  print "ENTER foo"
  print “Hello World”
  print "EXIT Foo"

This works but it has some issues

  • you had to modify the function
  • the modification must be reimplemented for other functions
  • notice that it if you change the name of the function for example to “bar” you’ll have to change code that prints the name of the function

Using decorators with the decorator module

Now let’s try with the decorator module

There are two steps:

- use @decorator  to create a decorator in this case called @tracing

- use the @tracing decorator on a function you want to trace

from decorator import *

def tracing (f, *args, **kw) :
  print "ENTER", f.func_name
  retval = f(*args,**kw)
  print "EXIT", f.func_name
  return retval

def foo() :
  print "Hello World"


And now what happens when we call foo()?


>>> foo()
Hello World
EXIT foo

Very nice!

The tracing() method just wraps a function call with with print statements


  • The function we are tracing didn’t need to be modified
  • we can reuse the tracing code
  • The tracing will use the correct function name.

Recommendation: Try it

This post only scratched the surface; you can find out more here: http://www.phyast.pitt.edu/~micheles/python/documentation.html