Pragmatic Programmer Issues

Decorators by Python

Lately, I’m using Django. So I also learn Python. And I found that python is very clean and nice language.

As we know Python allows that function can also be a parameter to another function. So code similar to this is ok.

def decorator(fun):
print fun.__name__
def my_fun():
print “hello world”

decorator(my_fun)

But Python provides some syntactic sugar so the code above is the same as this code:

def decorator(fun):
print fun.__name__
@decorator
def my_fun():
print “hello world”

So why it is so important, because I’m Java programmer and this allows me in elegant way to use something similar to Aspect. For example I can write cache decorator and apply it to every calculation intensive function.

class cache:
def __init__(self, function):
self.function = function
self.cache = {}
def __call__(self, *args):
try:
return self.cache[args]
except KeyError:
self.cache[args] = self.function(*args)
return self.cache[args]

Now for our propose I use a non optimal fibonacci recursive function.

def fib(n):
if n > 1:
return fib( n -1 ) + fib ( n -2 )
return 1

And simply measured that using enough large fibonacci number.

from time import gmtime, strftime
print “started %s” % strftime(“%a, %d %b %Y %H:%M:%S”, gmtime())
print fib(35)
print “ended %s” % strftime(“%a, %d %b %Y %H:%M:%S”, gmtime())

With and without @cache decorator. The output is

With @cache:

started Mon, 02 Jun 2008 20:32:41
14930352
ended Mon, 02 Jun 2008 20:32:41

and without:

started Mon, 02 Jun 2008 20:33:09
14930352
ended Mon, 02 Jun 2008 20:33:19

The conclusion is that it is great possibility to use such a class/function as I’m used to when using aspect with java.

Categories