Search code examples
pythonwrapperdecoratorpython-decoratorsword-wrap

Why is an error msg thrown when a function taking n parameters is passed to a sub function of a decorator function which contains 0 arguments


I am new to python and trying to understand the languages functions and features. When I run the below code, I get the error msg "wrap() takes 0 positional arguments but 2 were given".

class dec:

def decorator_function(orig):
    def wrap():
        print('hi')
        return orig
    return wrap

@decorator_function
def display_inf(name, age):
    print('dispInf ran with args ({},{})'.format(name,age))

display_inf('John',35)

I understand what the error msg is and if I change the wrap function to include 2 parameters as below, I wouldn't get this msg. However what I don't get my head around is why python is throwing the error. The display_inf function is passed to the decorator_function as expected, however as far as the wrap function is concerned, all it does is printing hi. It's not even using the function so why am I still getting this error if I am not using it. What goes behind the scene that causes the error.

def decorator_function(orig):
    def wrap(name, age):
        print('hi')
        return orig
    return wrap

Solution

  • When you use a decorator, your original function is replaced with the return value of the decorator. In your example, display_inf is replaced with wrap. Since wrap takes no arguments, when you try to call it with arguments, it fails.

    You seem to be thinking that wrap will be called once and is supposed to return the new function, but that's not how it works. The decorator itself (decorator_functrion) returns the new function, and in your case what it returns is wrap. wrap never gets to actually print anything because it's called with the wrong number of arguments.