Python Decorators are Just Wrappers
2020-05-06
2 minutes
Python decorators are just wrappers… that return functions
Part of my issue with understanding how decorators work was that I was treating them as a function/class that is returning a variable. I should have been thinking of them as a function/class returning a modified (i.e. decorated) function/class. As mentioned succinctly here, “Decorators are a form of metaprogramming; they enhance the action of the function or method they decorate.” So a decorator is just a wrapper of the function that you want to modify (that returns a function).
So if we want to decorate the function func
with the function decor
then the
sequence of evaluation would be modified_func = decor(func)(func_args)
.
Before going into what a decorator is, it’s useful to understand what it isn’t.
Casually wrapping a function in another function may not be sufficient. To
Illustrate this I’ve created a function to_decorate
(a function that returns
its input divided by 2) that I want to decorate.
def to_decorate(x):
return(x/2)
to_decorate(2)
The not_decorator
function below does not act as a decorator even though it is
a wrapper for to_decorate
. The not_decorator
function is modifying the
result of to_decorate
instead of modifying the to_decorate
function itself.
We have to actually evaluate the function that is the argument to
not_decorator
. Because we have to evaluate it, the function that is the
argument to not_decorator
must also take in an argument. The result is that
this function ends up returning a variable rather than a function/class.
# modifying the output of func so func has to be evaluated not modified
def not_decorator(func):
return(abs(func))
The code below will error out since the to_decorate
function is looking for an
argument.
not_decorated = not_decorator(to_decorate)
Passing an argument will allow it to run, but it’s still not a decorator since it’s returning a variable instead of a function.
not_decorated = not_decorator(to_decorate(2))
print(not_decorated)
Let’s define the function decorator
which takes a function as an input,
evaluates the absolute value of the result of the function (the modification), a
returns a function as opposed to the result.
We have to wrap the modification in the inner
wrapper otherwise we won’t be
able to return a function/class. This was the issue with not_decorator()
above.
…
What about modifying a function with multiple decorators?
…
What about passing arguments to decorators?
…
381 Words