Class based decorators in python

In the previous articles of Python decorator series we learnt to create a simple function based decorator, how it works under the hood and how to fix the doc strings.

In this article, we will learn to create a class based decorator and use it to deco…


This content originally appeared on DEV Community and was authored by Suresh Kumar

In the previous articles of Python decorator series we learnt to create a simple function based decorator, how it works under the hood and how to fix the doc strings.

In this article, we will learn to create a class based decorator and use it to decorate functions.


class HelloDecorator:
    """Simple class decorator"""

    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        """Simple class call method"""
        print(f'Calling {self.func.__name__}')
        result = self.func(*args, **kwargs)
        return result


@HelloDecorator
def add(a, b):
    """Simple function that returns sum of two numbers"""
    return a + b


if __name__ == '__main__':
    output1 = add(2, 2)
    print('Result:: ', output1)

Calling add
Result::  4

OK, We got the decorator working. Lets look at the help and name and doc attributes,

help(add) # --> prints class definition
print(add.__doc__) # --> prints Simple class decorator
print(add.__name__) # --> Raises AttributeError

Let's try to fix the doc strings,
use funct_tools.partial to define get magic method and then funct_tools.update_wrapper to let python know the wrapped function.

from functools import update_wrapper, partial


class HelloDecorator:
    """Simple class decorator"""

    def __init__(self, func):
        self.func = func
        # fixes __name__ and __doc__ attributes
        update_wrapper(self, func)

    def __get__(self, obj):
        """Fixes help description"""
        return partial(self, obj)

    def __call__(self, *args, **kwargs):
        """Simple class call method"""
        print(f'Calling {self.func.__name__}')
        result = self.func(*args, **kwargs)
        return result

now lets check the docs,

help(add) # --> prints
"""
add(a, b)
    Simple function that returns sum of two numbers
"""
print(add.__doc__) # --> prints "add"
print(add.__name__) # --> prints "Simple function that returns sum of two numbers"

Conclusion, while some may class based decorators prefer, I personally do not prefer class based decorator because of the extra boilerplate code to fix the doc strings.

In the next article, we will implement various kinds decorator recipes. Stay tuned for upcoming articles. Connect with me on twitter to get my future articles.


This content originally appeared on DEV Community and was authored by Suresh Kumar


Print Share Comment Cite Upload Translate Updates
APA

Suresh Kumar | Sciencx (2022-04-19T05:03:02+00:00) Class based decorators in python. Retrieved from https://www.scien.cx/2022/04/19/class-based-decorators-in-python/

MLA
" » Class based decorators in python." Suresh Kumar | Sciencx - Tuesday April 19, 2022, https://www.scien.cx/2022/04/19/class-based-decorators-in-python/
HARVARD
Suresh Kumar | Sciencx Tuesday April 19, 2022 » Class based decorators in python., viewed ,<https://www.scien.cx/2022/04/19/class-based-decorators-in-python/>
VANCOUVER
Suresh Kumar | Sciencx - » Class based decorators in python. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/04/19/class-based-decorators-in-python/
CHICAGO
" » Class based decorators in python." Suresh Kumar | Sciencx - Accessed . https://www.scien.cx/2022/04/19/class-based-decorators-in-python/
IEEE
" » Class based decorators in python." Suresh Kumar | Sciencx [Online]. Available: https://www.scien.cx/2022/04/19/class-based-decorators-in-python/. [Accessed: ]
rf:citation
» Class based decorators in python | Suresh Kumar | Sciencx | https://www.scien.cx/2022/04/19/class-based-decorators-in-python/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.