3

I tried to use function decorators, but in this example it dooesn't work for me, can you give me the solution ?

def multiply_by_three(f):
    def decorator():
        return f() * 3
return decorator

@multiply_by_three
def add(a, b):  
    return a + b

print(add(1,2)) # returns (1 + 2) * 3 = 9

Interpreter prints error: "TypeError: decorator() takes 0 positional arguments but 2 were given"

siemaeniu500
  • 115
  • 1
  • 9
  • 3
    It's telling the truth. Your `decorator` function doesn't take any arguments, byt when you call `add(1,2)`, you are eventually calling `decorator(1,2)`, because this is what you return from your `multiply_by_three` method. Also, consider not calling it "decorator" because that will make it very confusing to discuss (since `multiply_by_three` is the actual decorator). – larsks Aug 20 '17 at 12:36

1 Answers1

5

When you use a decorator, the function you return from the decorator replaces the old function. In other words, the decorator function in multiply_by_three replaces the add function.

This means that each functions signature's should match, including their arguments. However, in your code add takes two arguments while decorator takes none. You need to let decorator receive two arguments as well. You can do this easily by using *args and **kwargs:

def multiply_by_three(f):
    def decorator(*args, **kwargs):
        return f(*args, **kwargs) * 3
    return decorator

If you now decorate your function and run it, you can see it works:

@multiply_by_three
def add(a, b):  
    return a + b

print(add(1,2)) # 9
Christian Dean
  • 22,138
  • 7
  • 54
  • 87