Python ProgrammingPython Programming

How to pass Class fields to a decorator on a class method as an argument?

import functools

# imagine this is at some different place and cannot be changed


def check_authorization(some_attr, url):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print(f"Welcome Message: '{url}'...")
            return func(*args, **kwargs)
        return wrapper
    return decorator

# another dummy function to make the example work


def do_work():
    print("work is done...")


def custom_check_authorization(some_attr):
    def decorator(func):
        # assuming this will be used only on this particular class
        @functools.wraps(func)
        def wrapper(self, *args, **kwargs):
            # get url
            url = self.url
            # decorate function with original decorator, pass url
            return check_authorization(some_attr, url)(func)(self, *args, **kwargs)
        return wrapper
    return decorator


class Client(object):
    def __init__(self, url):
        self.url = url

    @custom_check_authorization("some_attr")
    def get(self):
        do_work()


# create object
client = Client('Hello World')

# call decorated function
client.get()
Output
Welcome Message: 'Hello World'...
work is done...