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
return fn(*args, **kwargs) # why am i returning this?
Please consult the documentation. Python interprets your code at distinct times:
import
time (when we generate bytecode for functions)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.