Search code examples
python-3.xpython-decorators

Why am i requiring to return again inside the higher order function


Been looking into some decorators in python3. Below is a code snippet. Why am i required to return the function (fn), when it is called inside the wrapper function

from functools import wraps

def log_function_data(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        print(fn.__name__)
        print(fn.__doc__)
        return fn(*args, **kwargs)   #why am i returning this?
    return wrapper

@log_function_data
def add(x,y):
    '''Adds 2 numbers and returns'''
    return x + y

The add function is already returning the result of the operation. So i call the add function without the decorator the return works like:

def add(x,y):
    '''Adds 2 numbers and returns'''
    return x + y

result = add(2,3) ##have the result = 5

Solution

  •     return fn(*args, **kwargs)  # why am i returning this?
    

    Please consult the documentation. Python interprets your code at distinct times:

    1. once, at import time (when we generate bytecode for functions)
    2. repeatedly, at run time (when you call the function)

    You could choose not to return fn, but that would cause an important change to the generated bytecode, resulting in a decorated function which returns the default value of None. Since the generated bytecode wouldn't even bother calling add(), it's hard to call the final result a "decorated" function at all, it's more like a completely different function that ignored the fn passed into it.

    To better understand decoratoring, you might find it instructive to play around with dis. I recommend making a one-line change in your source code, and noticing the diff's between the variant bytecodes.