Python decorator
With the help of decorator, you can change the behavior of a function without modifying the function code. This means, you could execute some code that you would like to before/after the original function and anyone, who is calling this function, would not need to change even a single line of code.
Some of the simplest examples of this additional code are
logging before calling the original function.
measuring the time a function takes to run.
caching the output of a function.
Python decorator is a function which takes another function as input and returns a function.
def my_decorator(func):
def new_function(*args,**kwargs):
# do some work
return new_function
This is the basic concept you need to understand. We will get into details about how decorator works and how to write it.
You can apply a decorator to a function using @ sybmol
def my_decorator(func):
def new_function(*args,**kwargs):
# do some work
return new_function
@my_decorator
def foo(args):
pass
Now lets get into some details.
Initially we had a function called foo. Note that foo is just a name which is pointing to a function object.
When you apply a decorator, it does the following
foo = my_decorator(foo)
Since my_decorator is a function which takes a function and returns a function, it took foo function as input and returned a new function and most importantly assigned the new function to foo. So now foo is pointing to new _function instead of original function.
decorator takes the function as input on which it is applied.
After applying the decorator, there is no change required in the calling code. That means this new function should be able to accept the same arguments which the original function was accepting. To do this, decorator makes use of args and kwargs.
def my_decorator(func):
def new_function(*args,**kwargs):
# do some work
print('calling foo')
result = func(*args, **kwargs)
return result
return new_function
@my_decorator
def foo(name,age):
pass
foo('abc',20)
# this is translated to
new_function = my_decorator(foo)
foo = new_function
foo('abc',20)
#or
my_decorator(foo)('abc',20)
In this example, decorator created a function which logs a statement before calling the original function. Then calls the original function with the arguments passed and returns the result.
This is the simplest form of decorator. There are some advance usage of decorator like property which we will get into later.