How to write a decorator in Python(function based)

Posted by Afsal on 24-Jan-2022

A decorator is a class or function which modifies the behavior of another function without modifying the code. The decorator accepts a function as an input argument and wraps it inside another function. Today we are going to learn about function-based decorators.

Let’s look at an example. Consider a case where we need to execute a function 5 times. A decorator can be used in these cases.

 

def print_5_times(function):
    def inner(*args, **kwargs):
        for _ in range(5):
            function(*args, **kwargs)
    return inner

@print_5_times
def print_hello_world():
    print(“Hello World”)

print_hello_world()

In the above example, I have added a print_5_times decorator to the hello_world function. Hello World will print 5 times when the function is called.

How this works:

When the decorator is added to  print_hello_world, print_hello_world becomes the inner function of the decorator.

print_hello_world = print_5_times(print_hello_world)
print(print_hello_world)

 Now, the print_hello_world is an inner function written in the decorator. If we print(print_hello_world) the output will be as given below.

<function print_5_times.<locals>.inner at 0x7fc420b30d30> something like this

When we call the print_hello_world function, the inner function of the decorator is also called. The inner function loops 5 times and executes the input function which is the actual function.

Now, if we want to configure the number of executions then we need a modification to the decorator. This time we need an extra layer of nesting. Let's consider the below example.

def print_n_time(number_of_time):
    def decorate(func):
        def inner(*args, **kwargs):
            for _ in range(number_of_time):
                func()
        return inner
    return decorate

@print_n_times(10)
def hello_world():
    print(“hello world”)

hello_world()

Here in this example, “Hello_world” becomes “hello_world = print_n_times(10)(hello_wolrd)” which is the inner function of the decorator print_n_time(10). This will return a decorated function. We can call the decorated function with the hello_world function. So, when we print hello_wolrd we can see that the output like below:

hello_world = print_n_times(10)(hello_world)
<function print_n_times.<locals>.decorator.<locals>.inner at 0x7fd492514040>

When we call the hello_world function, the inner function is also called which is to loop the initial function n times and execute it.

Hope you have learned from this post. If you have any suggestions please mail to afsal@parseltongue.co.in