Understanding Python Decorators
Suppose, you have a function and you want to change its behavior without changing its code. How do you do that? Yes, you need to use decorators!
Before, discussion about decorators let’s have a brief discussion about function.
Function is a named block of code which performs a specific task (yes “a specific task”, if a function performs more than one task then the function should be split into multiple functions. It may differ depending on situation, it’s just a trade-off!).
Here, we have declared a function named describe_myself
which prints the value of given argument (name) .
In Python, functions are first-class object (first class citizen too!). Read about first-class object here.
Higher-order Function
Functions in python can be higher-order. When a function takes a function as argument and/or returns a function then it’s called higher order function.
Here, our_higher_order_function
takes another function as argument and calls the function.
Inner Function
A function can be inside another function. It’s called inner function. Inner functions are scoped inside its parent function.
We are creating and calling child function inside parent function. child functions are not directly accessible outside of parent function. If we want to call our_child_function
from outside of our_parent_function
then we shall get an error :
But, here is a interesting trick! As in Python, a function can return another function then we can take it’s benefit.
Here, we are returning the reference of our_child_function
, storing in child_function
and calling it. Interesting, No?
Our first decorator
Let, we want to print
our country’s name along with our name but we won’t change our describe_myself
function.
Here, our_first_decorator
takes func
as argument
, modifies its behavior and returns a new function. We are assigning the modified functions reference to describe_myself
variable and calling through it.
Yes, this is our first decorator! A decorator wraps a function by modifying its behavior. We’ve done the same thing in the previous code.
Polish our first decorator
Using our_first_decorator
is not looking awesome yet. We can use it in smarter way by using @ symbol (sometimes, @ is called pie-decorator) .
The following block of code will do the same as previous one.
Here we’ve hard coded “Bangladesh” in our wrapper function. We can pass arguments for the wrapper
too!
It looks nicer now!
Introspection our decorator
Let’s introspect our function and decorator:
Wait, for print(describe_myself.__name__)
it shows that name of describe_myself
function is wrapper
! Shouldn’t it be describe_myself
?
However, after being decorated, describe_myself
has gotten confused about its identity. It reports of being the wrapper
inner function of our_first_decorator
. Though this information is technically not wrong but not very useful information.
We can solve this issue by using @functools.wraps
decorator. A custom decorator should use this decorator to preserve its information.
It looks fine now!
In this brief discussion, we have completed some basics of python decorator and developed our first python decorator! :)
You can also read :
📝 Read this story later in Journal.
🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >