2

I am learning decorator functions in python and I am wrapping my head around the @ syntax.

Here is a simple example of a decorator function which calls the relevant function twice.

def duplicator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)
        func(*args, **kwargs)
    return wrapper

If I understand correctly, it appears that:

@duplicator
def print_hi():
    print('We will do this twice')

Is equivalent to:

print_hi = duplicator(print_hi)
print_hi()

However, let's consider if I move to a more complex example. E.g. instead of calling the function twice, I want to call it a user-defined amount of times.

Using an example from here: https://realpython.com/primer-on-python-decorators/

def repeat(num_times):
    def decorator_repeat(func):
        @functools.wraps(func)
        def wrapper_repeat(*args, **kwargs):
            for _ in range(num_times):
                value = func(*args, **kwargs)
            return value
        return wrapper_repeat
    return decorator_repeat

I can call this via:

@repeat(num_times=4)
def print_hi(num_times):
    print(f"We will do this {num_times} times")

However, this is most certainly not equivalent to:

print_hi = repeat(print_hi)

Because we have the extra argument of num_times.

What am I misunderstanding? Is it equivalent to:

print_hi = repeat(print_hi, num_times=4)
3
  • I believe you pretty much got it right. Commented Oct 2, 2018 at 10:02
  • repeat(num_times) returns a function and that function is used to decorate print_hi. Commented Oct 2, 2018 at 10:04
  • 1
    @deco def foo is equivalent to foo = deco(foo), and @deco(args) def foo is equivalent to foo = deco(args)(foo). Actually it makes perfect sense. Commented Oct 2, 2018 at 10:07

2 Answers 2

6

For the case of the repeat decorator, the equivalent is:

print_hi = repeat(num_times=4)(print_hi)

Here, repeat takes a num_times argument and returns the decorator_repeat closure, which itself takes a func arguments and returns the wrapper_repeat closure.

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

Comments

4

repeat(num_times) returns a function and that function is used to decorate print_hi.

@repeat(num_times=4)
def print_hi(num_times):
    ...

amounts to

f = repeat(num_times)
print_hi = f(print_hi)

The function that repeat returns is decorator_repeat, which decorates print_hi.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.