Sunday, December 5, 2010

python decorators

Decorator is a very expressive language feature in python. It helps developers to write cleaner, modular code that is easier to extend and maintain. It also helps implement AOP and decorator pattern in python.

Decorator syntax
To declare a decorator function, we can define a function that takes a another function as argument and returns a function. The usage of decorator is very simple, just add a line begins with '@' symbol and the name of the decorator before the function to be decorated.

 1 def decorator(func):
 2     def new_func():
 3         print "decorator message"
 4         func()
 5     return new_func
 6
 7 @decorator
 8 def foo():
 9     print "hello world"
10
11 foo()

The effect is when we call foo function, besides print "hello world" message, the message "decorator message" is also printed. That is, the decorator function extends foo function's behavior.
The code above is equivalent to:
 

 1 def decorator(func):
 2     def new_func():
 3         print "decorator message"
 4         func()
 5     return new_func
 6
 7 def foo():
 8     print "hello world"
 9
10 foo = decorator(foo)
11 foo()

Decorators can also accept arguments, as long as it returns a decorator function that takes a function as argument.
 1 def decorator_with_arg(arg):
 2     def decorator(func):
 3         def new_func():
 4             print arg
 5             func()
 6         return new_func
 7     return decorator
 8
 9 @decorator_with_arg("arg for decorator")
10 def foo():
11     print "hello world"
12
13 foo()


The example above is equivalent to :

 1 def decorator_with_arg(arg):
 2     def decorator(func):
 3         def new_func():
 4             print arg
 5             func()
 6         return new_func
 7     return decorator
 8
 9 def foo():
10     print "hello world"
11
12 foo = decorator_with_arg("arg for decorator")(foo)
13 foo()
The decorator_with_arg function creates a closure, so that the arg argument can still be used after the decorator_with_arg returned. Since it's possible for a decorator to accept arguments, the decorator's behavior can changed based on the argument passed in. So it's possible to write more flexible code.

A more practical example
Here is a more practical example. We create a tracable decorator which is a debugging utility. It will keep records of the number of times that a function decorated with it is invoked.
 1 trace_log = {}
 2
 3 def tracable(func):
 4     def decorated_func(*arg, **kwarg):
 5         if not trace_log.has_key(func.__name__):
 6             trace_log[func.__name__] = 1
 7         else:
 8             trace_log[func.__name__] += 1
 9         func(*arg, **kwarg)
10
11     return decorated_func
12
13 def print_trace_log():
14     for key, value in trace_log.items():
15         print "%s called %d times"%(key, value)
16
17 @tracable
18 def foo1():
19     print "foo1"
20
21 @tracable
22 def foo2(arg, kwd="keyword arg"):
23     print "foo2"
24     print arg
25     print kwd
26
27 @tracable
28 def foo3():
29     print "foo3"
30
31 foo1()
32 foo1()
33 foo1()
34 foo2(12)
35 foo2(13)
36
37 print_trace_log()

If we run the code, it will prints that foo1 function is called three times and foo2 function is called twice.
As the example showed, the code for implementing tracing is separated from business logic code contained within foo1 and foo2. The maintainability of the program is much higher than if the code for tracing is mixed with business logic code.

Summary
We got several benefits from decorator.
First, it helps achieve a better separation of business logic code and auxiliary code.
Second, it helps finding out where the auxiliary is used because decorator employs a very special syntax.
Third, we can extend or change our business logic without having to change existing code. New code can be implemented as a decorator.


References:
Charming Python: Decorators make magic easy
Decorators for Functions and Methods
PythonDecorators

9 comments:

Bhanu Sree said...

This information is really awesome thanks for sharing most valuable information.
Python Course in Hyderabad
Python Institute in Hyderabad
Python Online Training in Hyderabad
Python Training in Hyderabad
Python Training
Python Online Training

Thakur98 said...

Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder

ds324 said...

Great article essay typer toronto

sportstototopcom said...

Awesome blog. I enjoyed reading your articles. This is truly a great read for me. I have bookmarked it and I am looking forward to reading new articles.
스포츠토토

roulettesitetop said...

The contents of this blog are always very interesting, educative and informative, I must commend you for the good work you are doing here, keep it up.
룰렛사이트탑

trublogger said...

tremendous occupation for distributing this kind of helpful web site. Your net log isnt without help valuable anyway it's far also in truth imaginative as well. Sony Vegas Cracked

Let2know said...

Best advertise! this is an each level of simple to apply weblog that I can conclusively come steerage to more prominent age this yr! gratitude for useful broadcast. Sketchup 2022 Crack Free Download

Back linker said...

you have executed an uproarious errand upon this text. Its completely adjust and very subjective. you have even figured out how to make it decipherable and simple to make a get accord of into. you have a couple of precise composing competence. much obliged appropriately a lot. Happy Birthday Wish For Love

Dev said...

Awesome blog. I enjoyed reading your articles. This is truly a great read for me. https://brollyacademy.com/cyberark-training-in-hyderabad/