Useful cases to illustrate Decorators in python
Last Updated :
11 Dec, 2019
A decorator is a special kind of function that either takes a function and returns a function or takes a class and returns a class. Well, it can be any callable (i.e functions, classes, methods as they can be called) and it can return anything, it can also take a method. This is also called
metaprogramming, as a part of the program tries to modify another part of the program at compile time.
Let's dive into python decorators and find out what they can do. This will not be covering the basics or decorators with parameters, but some useful examples to illustrate the case.
Refer the below article to get the basics of Python decorators
Basically, a decorator takes in a callable, any object which implements the special method
__call()__
is termed as callable, adds some functionality and returns a callable.
Example 1:
Python3 1==
# Python program to demonstrate
# decorators
# Creating a decorator
def decorated_func(func):
def inner():
print("This is decorated function")
func()
return inner()
def ordinary_func ():
print("This is ordinary function")
decorated = decorated_func(ordinary_func)
decorated
Output:
This is decorated function
This is ordinary function
In the example shown above,
decorated_func()
is a decorator. In short, a decorator acts as a wrapper that wraps an object (does not alter the original object) and adds an new functionality to original object. This is a common construct, so Python has a syntax feature (called
Decorator
) to simplify this. For example,
This:
@decorated_func
def ordinary_func():
print("This is ordinary function")
is Equivalent to:
def ordinary_func():
print("This is ordinary function")
decorated = decorated_func(ordinary_func)
A simple example would be:
Example 2:
Input:
Python3 1==
def mul_decorator(func):
def wrapper(*args, **kwargs):
print('function', func.__name__, 'called with args - ', /
args, 'and kwargs - ', kwargs)
result = func(*args, **kwargs)
print('function', func.__name__, 'returns', result)
return result
return wrapper
@mul_decorator
def mul(a, b):
return a * b
mul(3, 3)
mul(3, b = 6)
Output:
function mul called with args - (3, 3) and kwargs - {}
function mul returns 9
function mul called with args - (3,) and kwargs - {'b': 6}
function mul returns 18
You can also use the built-ins as decorators
Example 3:
Python3 1==
# func will be func = type(func) -> <class 'function'>
@type
def func():
return 42
print(func)
# print doesn't return anything, so func == None
@print
def func2():
return 42
# Prints None
print(func2)
Output:
<class 'function'>
<function func2 at 0x7f135f067f28>
None
You can replace decorated object with something else
Example 4:
Python3 1==
# Creating a decorator
class function_1:
def __init__(self, func):
self.func = func
self.stats = []
def __call__(self, *args, **kwargs):
try:
result = self.func(*args, **kwargs)
except Exception as e:
self.stats.append((args, kwargs, e))
raise e
else:
self.stats.append((args, kwargs, result))
return result
@classmethod
def function_2(cls, func):
return cls(func)
@function_1.function_2
def func(x, y):
return x / y
print(func(6, 2))
print(func(x = 6, y = 4))
func(5, 0)
print(func.stats)
print(func)
Output:
3.0
1.5
Traceback (most recent call last):
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 29, in
func(5, 0)
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 11, in __call__
raise e
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 8, in __call__
result = self.func(*args, **kwargs)
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 23, in func
return x / y
ZeroDivisionError: division by zero
Notice how the original
"func"
was replaced by an instance of
"function_1"
, which can be used in the same way as the original function.
You can create relation with other objects in system
Example 5:
Python3 1==
def dict_from_func(func):
return {func.__name__: func}
activity = {}
@activity.update
@dict_from_func
def mul(a, b):
return a * b
@activity.update
@dict_from_func
def add(a, b):
return a + b
print(mul)
print(activity)
print(activity['mul'](2, 5))
Output:
None
{'mul': <function mul at 0x7f0d2209fe18>,
'add': <function add at 0x7f0d220a2158>}
10
Here, in the example 5, we have used
dict.update
method as a decorator, even if it is not intended for this. This, is possible because
dict_from_func
returns a dict, and
dict.update
takes a dict as an argument.
Actually, This:
@activity.update
@dict_from_func
def mul(a, b):
return a * b
Equals this -
def mul(a, b):
return a * b
mul = activity.update(dict_from_func(mul))
Conclusion
Decorators is an interesting and amazing feature and can be used for variety of purposes. It's not just
"function or class that takes function or a class and returns a function or a class".
Similar Reads
How to use Function Decorators in Python ?
In Python, a function can be passed as a parameter to another function (a function can also return another function). we can define a function inside another function. In this article, you will learn How to use Function Decorators in Python. Passing Function as ParametersIn Python, you can pass a fu
3 min read
Data Classes in Python | Set 2 (Decorator Parameters)
Prerequisite: Data Classes in Python | Set 1 In this post, we will discuss how to modify the default constructor which dataclass module virtually makes for us. dataclass() decorator - @dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False) By changing t
4 min read
Dispatch Decorator in Python
Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behavior of function or class. Decorators allow us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it. Example: Python3 # defining a deco
2 min read
call() decorator in Python
Python Decorators are important features of the language that allow a programmer to modify the behavior of a class. These features are added functionally to the existing code. This is a type of metaprogramming when the program is modified at compile time. The decorators can be used to inject modifie
3 min read
Closures And Decorators In Python
Closures and decorators are powerful features in Python that allow for more advanced and flexible code patterns. Understanding these concepts can greatly enhance your ability to write clean, efficient, and reusable code.Why Python decorators rather than closures?Python decorators are preferred over
3 min read
Decorator to print Function call details in Python
Decorators in Python are the design pattern that allows the users to add new functionalities to an existing object without the need to modify its structure. Decorators are generally called before defining a function the user wants to decorate. Example: Python3 # defining a decorator def hello_decora
3 min read
Chain Multiple Decorators in Python
In this article, we will try to understand the basic concept behind how to make function decorators and chain them together we will also try to see Python decorator examples. What is Decorator In Python?A decorator is a function that can take a function as an argument and extend its functionality an
2 min read
Memoization using decorators in Python
Recursion is a programming technique where a function calls itself repeatedly till a termination condition is met. Some of the examples where recursion is used are a calculation of fibonacci series, factorial, etc. But the issue with them is that in the recursion tree, there can be chances that the
3 min read
Implementing LRU Cache Decorator in Python
LRU is the cache replacement algorithm that removes the least recently used data and stores the new data. Suppose we have a cache space of 10 memory frames. And each frame is filled with a file. Now if we want to store the new file, we need to remove the oldest file in the cache and add the new file
3 min read
Decorators in Python
In Python, decorators are a powerful and flexible way to modify or extend the behavior of functions or methods, without changing their actual code. A decorator is essentially a function that takes another function as an argument and returns a new function with enhanced functionality. Decorators are
10 min read