Decorator Design Pattern in Python
The decorator pattern is a structural design pattern that allows us to dynamically add functionality to classes without creating subclasses and affecting the behavior of other objects of the same class.
This can be useful for adding logging, caching, or other functionality to objects.
Understand the Decorator pattern
A decorator is a function that takes another function as input and returns a new function that has the same functionality as the original function, but with some additional functionality added.
This pattern helps to implement reusable and shareable code to other components. For example, you want to check permissions before executing the function, this is extremely useful pattern, and it is also widely used.
Let’s look at the pattern how it works!
Decorators work by using the @ symbol to bind a decorator function to a target function.
For example, the following code creates a decorator function that logs the execution time of a function:
import time
def log_execution_time(func):
"""
Implements and return wrapper function
"""
def wrapper(*args, **kwargs):
"""
This function implements additional functionalities
wrapping to original function
"""
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"The execution time of {func.__name__} was {end - start}")
return result
return wrapper
We can then use the @ symbol to bind the log_execution_time decorator to a target function:
import time
@log_execution_time
def prepare_dish(name):
print(f"Cooking {name}...")
time.sleep(2) # preparing dish
print(f"Dish {name} is ready")
prepare_dish("Maxican rice")
""" Result of above function would be as following
Cooking Maxican rice...
Dish Maxican rice is ready
The execution time of prepare_dish was 2.009246826171875
"""
This will create a new function called prepare_dish that logs the execution time of the prepare_dish function.
When can we use decorators?
Decorators can be used to add functionality to objects without modifying their original code. This can be useful for adding logging, caching, or other functionality to objects.
Decorators can also be used to simplify the code of a program. For example, we could use a decorator to wrap a complex function in a simple function that takes care of all the details.
Conclusion: - This design pattern is vastly used pattern, so I hope this article helped to understand how you can use this pattern in your programs as well.
Thank you for reading!