Friday, 3 August 2012

Python Decorators

 Python has a lot to offer in terms of manipulation of existing code, which can make it work in more ways than it is offered in a simple code.

What are decorators?

As explained in Wikipedia A decorator is any callable Python object that is used to modify a function, method or class definition. A decorator is passed the original object being defined and returns a modified object, which is then bound to the name in the definition. Now what the above statement means can be explained using an example.

@cricket
@fav_color_team("blue")                                                                  
def player()                                                                     
   pass                                                                                                                       
In the above example the @ signifies a decorator, what it does is that it decorates player function such that the color "blue", would be printed prior to the player function running. Decorators must return a decorator, which is then called with the object to be decorated as its arguments.

def fav_color_team(color):
   def decorator(func):
       def wrapper():
          print (color)
          func()
       return wrapper
       return decorator
Python decorators add functionality to functions and methods at definition time, and thus are a higher-level construct than decorator-pattern classes than object oriented programming languages.

Function decorators

It is a decorator applied to a function definition by placing it on the line before that function definition begins. Eg:-

class new_decorator(object):
    def __init__(self, f):
        print"inside new_decorator.__init__()"
        f()
    def __call__(self):
       print"inside new_decorator.__call__()"
@new_decorator
def functn():
   print"inside functn"
print"Finished decorating"
functn()

The f() indicates completion of function definition. On running the code we get the following in the same order. 
  
>>>inside new_decorator.__init__()
>>>inside functn()
>>>Finished decorating functn()
>>>inside new_decorator.__call__()

Now to explain decorator with an implementation.


def double (func) :
     def wrapper(*args, **kwargs) :
             return func(*args, **kwargs) * 2
     return wrapper
 
 @double
 def interest(amt) : return amt*.09*2

>>> interest(100)
36.0
 
The function double accepts a function as parameter. The *args, **kwargs Those arguments are called "keyword arguments".
 Essentially, they are place holders for multiple arguments, and they are extremely useful especially when you need to pass a different number
 of arguments each time you call the function.
 
Decorator help in manipulation of functions but increase the complexity of the code, so if ease of understanding is the criteria then we can restrict the use of decorators  
  

  

No comments:

Post a Comment