0

I have the following code:

class Foo:
    iterations = 3

class Bar(Foo):
    @test_decorator(<????>)
    def hello(self):
        print("Hello world!")

def test_decorator(input):
    def my_decorator(func):
        def wrapper(*args, **kwargs):
            print("Something is happening before the function is called.")
            for _ in range(input):
                func(*args, **kwargs)
            print("Something is happening after the function is called.")
        return wrapper
    return my_decorator

I would like to pass my iterations variable which is in the parent class to the decorator test_decorator which is in my child class, instead of <????>

I tried the following ways:

  • self.iteration doesn't work since we don't have access to self
  • Foo.iterations doesn't work because it will act as a constant, if we change iterations "hello world" will be displayed only 3 times instead of 5 (as in the example below)

Example:

b = Bar()
b.iterations = 5
b.hello()

# "hello world" will be displayed 3 times

Is there a way to do this or is it anti pattern to python ?

2
  • 1
    The decorator is only called once, when the function is defined. If you want the function to change when Foo.iterations does, I do not think that specific pattern is the solution. Commented Mar 1, 2022 at 17:02
  • "Foo.iterations doesn't work because it will act as a constant, if we change iterations "hello world" will be displayed only 3 times instead of 5 (as in the example below)" that's how passing a value to a decorator (or any function) would always work Commented Mar 1, 2022 at 17:10

1 Answer 1

1

I found a solution to your problem. The idea is to write your own decorator.

Since that decorator is a function wrapping your method, it has access to the class instance using the *args first index. From there, you can access the iterations variable:

def decorator(iterations, source):
    def inner_transition(func):
        return func
    return inner_transition

def custom_transition(source):
    def inner_custom_transition(func):
        def wrapper(*args, **kwargs):
            iterations = args[0].iterations
            return decorator(iterations=iterations, source=source)(func)(*args, **kwargs)
        return wrapper
    return inner_custom_transition

class Foo:
    iterations = 3

class Bar(Foo):
    @custom_transition(source="my_source")
    def hello(self, string_to_show, additional_string = "default"):
        print(string_to_show)
        print(additional_string)

bar = Bar()
bar.hello("hello", additional_string="++++")

Result:

hello
++++
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.