How to implement custom Decorator in Python

I am a Software Engineer. I have worked with different languages like NodeJS and Python. I have keen interest in Backend Engineering, Cloud Native Technologies and System Architecture.
Search for a command to run...

I am a Software Engineer. I have worked with different languages like NodeJS and Python. I have keen interest in Backend Engineering, Cloud Native Technologies and System Architecture.
No comments yet. Be the first to comment.
What is a Bastion host? A bastion host is a server whose purpose is to provide access to a private network from an external network, such as the Internet. Because of its exposure to potential attack, a bastion host must minimize the chances of penetr...

What is helm? Helm is a package manager for Kubernetes. It makes updates and rollback of applications more efficient and improves team collaboration. Kubernetes objects are challenging to manage Helm automates maintenance of YAML manifests for Kubern...

Introduction Automation is the key to streamlining your work processes for any software development project. GitHub actions allow you to add your software development lifecycle workflows directly to your repository. GitHub Actions is a continuous int...

Flake8 is a popular lint wrapper for python. In this article, we will understand the uses of flake8 against our python projects. What is flake8? Install flake8 in your project Run flake8 against your project Configure flake8 in config.cfg What ...

In this article, we will go through the installation of Kubernetes in your local system and run a simple nginx server via kubernetes. We need to follow this process Introduction to kubernetes Install minikube locally Run your first pod Access kub...

A decorator pattern is a well-known structural design pattern used to add new behavior to an existing object dynamically without altering already existing behavior. Decorator works by placing the object inside wrapper objects to add the functionality of the wrapper objects to the wrapped object.
By using decorator pattern, you can achieve the Signle-Responsibilty Principle by dividing the responsibilities among different functions. It also helps to maintain Open-Close Principle as you can add any new functionality to a new object without modifying the existing object's functionality.
def func_a(arg):
print("I am from A with argumnet "+ arg)
def decorator(func, arg):
func(arg)
main(func_a, "C")
I am from A with argumnet C
In the above example, the decorator function is working as a higher-order function which is taking a function as an argument and calling it. Right now it's not doing any other task. Let's assign a task to the decorator function.
def func_a(arg):
print("I am from A with argumnet "+ arg)
def decorator(func, arg):
print("I am in decorator with argument " + arg)
func(arg)
func_a("D")
I am from A with argumnet D
In the above example, I'm calling the function and it's printing the line mentioned above as expected.
decorator(func_a, "C")
I am in decorator with argumnet C
I am from A with argumnet C
Now I've added additional behavior to the existing func_a by adding it inside a decorator without changing its existing behavior.
Now Let's come to Python decorators
def decorator(func):
def helper(arg):
print("I am in decorator with argumnet " + arg)
func(arg)
return helper
def func_a(arg):
print("I am from A with argumnet "+ arg)
decorated_func = decorator(func_a)
decorated_func("C")
I am in decorator with argumnet C
I am from A with argumnet C
The above code in python can also be written like
def decorator(func):
def helper(arg):
print("I am in decorator with argumnet " + arg)
func(arg)
return helper
@decorator
def func_a(arg):
print("I am from A with argumnet "+ arg)
fun_a("C")
I am in decorator with argumnet C
I am from A with argumnet C
The "@" symbol in python is shorthand for writing decorators.
Let's go with a more realistic example where we can use a decorator effectively
def hanle_index_exception(func):
def helper(arr, pos):
if pos >= len(arr):
return "position is greater that list length."
return func(arr, pos)
return helper
@hanle_index_exception
def value_at_position(arr , pos):
return arr[pos]
arr = [1, 3, 5, 7]
val_1 = value_at_position(arr, 2)
print(val_1)
val_2 = value_at_position(arr, 4)
print(val_2)
5
position is greater that list length.
In the above example, we're using a decorator to handle index out-of-bound exceptions.
Multiple decorators can also be chained in python means decorating a function multiple times.
Here is a simple example:
def remove_whitespaces(func):
def hepler(name):
name = name.strip()
func(name)
return hepler
def format(func):
def hepler(name):
name = name.capitalize()
func(name)
return hepler
@remove_whitespaces
@format
def print_name(name):
print(name)
print_name(' akash ')
Akash
In the above example, remove_whitespaces decorator removes the whitespaces first. Then format decorator made the first letter capitalized. You should maintain the order correctly when adding more than one decorator as the topmost one will be applied first.
I hope now we have a better understanding of how to use decorator in python, you can easily use some decorator in your next project.
Happy Learning !!