Search code examples
pythondecoratorpython-decorators

Decorator flow and process


def logger(func):
    def inner(*args, **kwargs): #1
        print ('Arguments were: {}, {}'.format(args, kwargs))
        return func(*args, **kwargs) #2
    return inner

def add (x,y):
    return x+y

add = logger(add)
add(1, 2)

Code without using @logger, basically replacing it with add = logger(add).

def logger(func):
    def inner(*args, **kwargs): #1
        print ('Arguments were: {}, {}'.format(args, kwargs))
        return func(*args, **kwargs) #2
    return inner

@logger
def add (x,y):
    return x+y

add(1, 2)

Code using @logger, add = logger (add) is removed.

Both are with the same and correct output

I'm still learning python and trying to understand how decorator works for these 2 examples.

I would like to know how the flow works. I get that @logger is the same as add = logger(add), where the example then used add (1,2). This means that add(1,2) = logger(add(1,2))?

However, if this is the case, why does it not work when I try logger(add(1,2))?

Basically I'm trying to combine

add = logger(add)
add(1,2)

to something like

logger(add(1,2))

which is not working. Purpose of combining it is so that I can understand example much better.


Solution

  • You are trying to 'decorate' the return value of the add() function call, not the add function itself.

    The proper equivalent would be to use:

    logger(add)(1, 2)
    

    so use the return value of logger() as the function to pass the 1, 2 arguments to.

    In other words, you need to substitute the right call. It may be easier to understand if you used a different name for the result of the decorator call:

    decorated = logger(add)
    decorated(1, 2)
    

    and then simply substitute decorated for the original logger(add) call to:

    logger(add)(1, 2)