Class Decorator practical uses - Part 2

Last part we have seen about function decorator and how to use it to add extensions to existing functions. We have seen how decorator are useful, today we can see about how to use class based decorator which will provide extension functionalities to existing functions. How we can configure a class decorator during creation so that we can configure a decorator for our need. Lets get started with code.

def func(msg):
    print(f"Hai programmer we got this message {msg} for you ")



if __name__ == "__main__":
    func("Hello Developer")

Now for adding a class decorator we need to understand two things one is how the constructor is invoked for a class and how functors is used while invoking an object of a class. While creating a instance of the  class like below.

class MyDecorator:
    def __init__(self, func):

obj = MyDecorator(func)

Now we created an instance passing function as a parameter object. Since function is a first class functions in python it can be passed as a parameter to the __init__() function. 

To make the object callable in python that is it acts like a functor we can override __call__ dunder. Hence below code will produce output like below.

class MyDecorator:
    def __init__(self, func):
        print("calling __init__ method")
        self._func = func

def __call__(self, msg):
        print(f"calling functor passing {msg}")

if __name__ == "__main__":
    obj = MyDecorator(func)
    obj("hello world")


Output:

PS D:\Dinesh\Project\Django> python sample.py

calling __init__ method

calling functor passing hello world

Now I can use these two concepts about to create a class decorator like below:

func = MyDecorator(func)

if __name__ == "__main__":
    func = MyDecorator(func)
    func("hello world")

Here I overriden the func method with a class MyDecorator instance and passing its __call__ method the actual message which acts a decorator here. With this I create a whole code like below. In the code below I have processed the input parameter of func and the return value of func using decorator. 

import os


class MyDecorator:
    def __init__(self, func):
        print("calling __init__ method")
        self._func = func
   
    def __preprocessing(self, msg):
        self._msg = msg.upper()
   
    def __postprocessing(self, value):
        self._value = value.upper()
   
    def __call__(self, msg):
        print(f"calling functor passing {msg}")
        self.__preprocessing(msg)
        return_value = self._func(self._msg)
        self.__postprocessing(return_value)
        return self._value

@MyDecorator
def func(msg):
    print(f"Hai programmer we got this message {msg} for you ")
    return "hai reviewer nice to meet you"

if __name__ == "__main__":
    print(func("hello world"))

Output:

PS D:\Dinesh\Project\Django> python sample.py

calling __init__ method

calling functor passing hello world

Hai programmer we got this message HELLO WORLD for you

HAI REVIEWER NICE TO MEET YOU

In the next article I will show you how to configure the decorator parameter and use it control the pre-processing and post-processing with practical example of how to use it in data processing.

Comments

Popular posts from this blog

Decorators in python - Part 1

Public key cryptogrphy - How certificate validation works using certificate chain