Dynamic Decorators in Python

77 views Asked by At
from functools import wraps

WRAPTYPE = "DOES NOT WORK"

class Test():
    def __init__(self,wrapType):
        globals()["WRAPTYPE"] = wrapType
    
    def with_provider(wrapType):
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                print("Argument passed to with_provider:", wrapType)
                return func(*args, **kwargs)
            return wrapper
        return decorator

    # Example usage
    @with_provider(WRAPTYPE)
    def example_function(self):
        print("Inside example_function")

#%%
t = Test("WORKS")
t.example_function()

I want to be able to pass wrapType argument to the decorator at class initialization,, so that it prints "Argument passed to with_provider: WORKS" Is this possible? It doesn't need to be done with globals(), if it can be done with self.wrapType=wrapType where that self makes it way to the with_provider it would be great.

I tried the class above and it does not work, since at class initialization the argument passed to the decorator seems to be immutable. Need if possible for the decorator to be within the class for code cleaness

1

There are 1 answers

7
One Nose On BEST ANSWER

Simply use a self first argument.

from functools import wraps

class Test():
    def __init__(self,wrapType):
        self.wrapType = wrapType
    
    def with_provider(func):
        @wraps(func)
        def wrapper(self, *args, **kwargs):
            print("wrapType property of class instance:", self.wrapType)
            return func(self, *args, **kwargs)
        return wrapper

    # Example usage
    @with_provider
    def example_function(self):
        print("Inside example_function")

#%%
t = Test("WORKS")
t.example_function()