Monday, November 19, 2018

Decorators in Python

A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it. This is also called meta-programming as a part of the program tries to modify another part of the program at compile time. Thus decorators allow you to make simple modifications to callable objects like functions, methods, or classes.

A few facts about functions is worth knowing to have a better understanding about decorator.

1. Different names can be bound to the same function object. For example -

    def display(msg):
          print(msg) 

    display("Decorators")
    new_display = display
    new_display("Decorators")

When we run the code, both functions display and new_display gives same output. Here, the names display and new_display refer to the same function object.

2. Functions can be passed as arguments to another function. In the code shown below this behavior is shown -

def incrementing(x):
return x + 1

def decreasing(x):

return x - 1

def operation(func, x):

result = func(x)
return result

value = operation(incrementing,5)

print(value)

The output of this program is shown below -




  
3. A function can return another function.

def operation ():
   
    def incrementing(x):
       
        x = x+1
        print(x)
    return incrementing   
   
       
val = operation()

val(6)
 

val(8)    

Here, incrementing() is a nested function which is defined and returned, each time we call operation (). See the output below -

 

 So based on the definition that a decorator takes in a function, adds some functionality and returns it, here is an example -


 def operation (func):
  
    def incrementing(x):
      
        x = x+1
        print("incrementing\n")
        print(x)
        func(x)
    return incrementing  
  
      
def reincreasing(x):
  
    x= x + 1
    print("\nreincreasing\n")
    print(x)
  
    return reincreasing


val = operation(reincreasing)

val(20)


The output of the program is shown below -

 


In the example shown above, operation () is a decorator. In the assignment step -

val = operation(reincreasing)

The function reincreasing() got decorated and the returned function was given the name val.

We can see that the decorator function added some new functionality to the original function. This is similar to packing a gift. The decorator acts as a wrapper. The nature of the object that got decorated (actual gift inside) does not alter. But now, it looks pretty (since it got decorated).

Generally, we decorate a function and reassign it as,

reincreasing = operation(reincreasing)

This is a common construct and for this reason, Python has a syntax to simplify this. We can use the @ symbol along with the name of the decorator function and place it above the definition of the function to be decorated. For example,

@operation
def reincreasing():
    x= x + 1
    print("\nreincreasing\n")
    print(x)
    return reincreasing

is equivalent to

def reincreasing():
    x= x + 1
    print("\nreincreasing\n")
    print(x)
    return reincreasing

reincreasing = operation(reincreasing)


In the next post we'll focus on classmethod decorators and static method decorators. Till then keep learning Python as Python is easy to learn!
Share:

0 comments:

Post a Comment