Most of the time people in python programming either never come across Decorators or if they, they are not able to understand it. In this article lets explore this not much explored Decorators.
Before getting into the main topic we need to look at two sub topics which forms the base of the main topic.
First Class Citizens
In python functions are first class citizens.
They can be stored like variables.
They can be passed as an argument inside function.
They can be returned from functions as values.
They act just like variables in python
Higher Order Function
HOF are functions that
accepts another function as argument
returns another function
Under the hood decorators uses these power of functions
What are Decorators ?
In layman's perspective it is someone who decorates something. Exactly, here as well decorators are something which decorates our function.
Decorators super charges a function and add extra functionality to it. It is simply a function that wraps another function and enhances it or modifies it.
Let's get started with coding
Now it is the time to create our own decorator
def my_decorator(func):
def wrap_func(*args, **kwargs):
print('***********')
func(*args, **kwargs)
print('***********')
return wrap_func
@my_decorator
def hello(greeting,msg):
print(greeting,msg)
hello('Hi Buddy', 'Welcome to Learning with Kritika Singhal' )
Output
***********
Hi Buddy, Welcome to Learning with Kritika Singhal
***********
Stepwise Explaination
Step1: my_decorator
is a function that contains a wrapper function
**Step2: ** wrap_func
is a function which wraps a function in it . It also adds some functionality to that function
**Step3: ** my_decorator
is the actual function which we want to enhance
Step4: Adding @
before a function attach that function to a decorator. Here @my_decorator
is the name of the decorator function
Use Case
After exploring above example you might be wondering what is actually the need of this decorator or where can we use it.
Decorators can be used to check user authentication before a task, for time calculation of a process, exception raising, debugging code , slowing down code and much more.
Lets see an example where I want to calculate the time taken by a function.
from time import time
def performance(func):
def wrapper(*args,**kwargs):
t1 = time()
result = func(*args, **kwargs)
t2 = time()
print(f' It took {t2-t1} ms')
return result
return wrapper
@performance
def multiply():
for i in range(100000000)
i*6
Output
It took 4.69677 ms
Here it is calculating the time before and after the execution of the function. Then it is calculating the difference of that time. Hence giving the time taken.
Multiple decorators can be used to a single function. They are executed bottom to top. Single decorator can also be used to multiple functions.