Decorators in Python

In Python, functions are the first class objects, which means that –
- Functions are objects; they can be referenced to, passed to a variable and returned from other functions as well.
2. Functions can be defined inside another function and can also be passed as argument to another function.
Decorators:A decorator in Python is any callable Python object that is used to modify a function or a class. A reference to a function or a class is passed to a decorator and the decorator returns a modified function or class.
Decorators allow us to wrap another function in order to extend the behavior of wrapped function/class, without permanently modifying it.
We have two different kinds of decorators in Python:
- Function decorators
- Class decorators
- Function Decorators:
Example 1:
def my_decorator(fn):
def wrapper():
print("Welcome")
fn()
print("Bye Bye")
return wrapper
def greet():
print("My Name is Lokesh!")
greet=my_decorator(greet)
greet()Output:
Welcome
My Name is Lokesh!
Bye Bye
Example 2:
def my_decorator(fn):
def wrapper():
print("Welcome")
fn()
print("Bye Bye")
return wrapper
@my_decorator
def greet():
print("My Name is Lokesh!")
greet()Output:
Welcome
My Name is Lokesh!
Bye Bye
Example 3: With arguments
import time
def calc_time(fn):
def wrapper(*args,**kwargs):
start=time.time()
fn(*args,**kwargs)
end=time.time()
print(f"{(end-start)*1000} MilliSeconds")
return wrapper
@calc_time
def pow(n):
return n**n
pow(15000)Output:
3.5295486450195312 MilliSeconds
2. Class Decorators:
Before we can define a decorator as a class, we have to introduce the __call__ method of classes. A function is a callable object, but lots of Python programmers don’t know that there are other callable objects. A callable object is an object which can be used and behaves like a function but might not be a function. It is possible to define classes in a way that the instances will be callable objects. The __call__ method is called, if the instance is called “like a function”, i.e. using brackets.
class decorator2:
def __init__(self, f):
self.f = f
def __call__(self):
self.f()
@decorator2
def foo():
print("inside foo()")
foo()Output:
inside foo()
