What is decorator in python?
Decorator is one of the coolest features of python, as the name suggests decorator is kind of for decorating something, which exists previously. A decorator is used for manipulating (adding, removing, or modifying features) the pre-existing functions or their output. It takes a function as an input, makes some changes, and returns it.
If you are having a hard time understanding this, then let’s go to the analog world and see what we can relate this to. So, here’s an analogy, suppose you have some cold water (pre-existing function) and you don’t like that, instead of that you want some warm water. So, what you will do is that you will pass it to a water heater (decorator) which will take your water (pre-existing function), turn it into warm water (make some changes) and finally return you some warm water. And Voila! This is all a decorator does
And this kind of behavior where a part of the program tries to modify another part of the program at the time of compilation is also known as metaprogramming.
Why do we need decorator?
Till the point, you might have understood that a decorator is something that takes a function as input, makes some changes, and returns it. But the question arises why we need it. The reason is we don’t always have access to pre-existing function’s code or imagine if you have written thousands or ten thousands of lines of code will you be able to navigate to that function easily, no right!
So, to address those problems our python uncle has added this nice feature.
Prerequisites
Before we discuss the implication part, I would like to revise some points about python and its function. So that you can recall and stay on track.
Also, I have attached all the codes of this article in a notebook for your ease so don’t worry about the code, you can use that notebook as a cheat sheet for a decorator.
Also read –> Everything you need to learn about NLP
- Everything in python is considered as an object which includes function and class as well.
- A function can be stored in a variable
- A function can be passed as an input to another function
- A function can be returned as an output from another function
How to use Decorators?
So, as we know what and why of decorators, let’s start with a simple decorator and see how it works.
Also, read -> How to do twitter sentiment analysis -hands-on with Elon Musk’s tweets.
Simple Decorator: This is a function that, just returns a name
Now we want this function to prefix that name with the title “Mr.”. But the condition here is that we can’t touch the original function. For that, we can use a decorator which will take the function ‘i_am’ and will transform its output from ‘Bob’ to ‘Mr. Bob’.
So this is a decorator which will take our original function as an input, then it’ll modify its output
How does it work?
Let’s see how it works, we have a nested function here.
Outer Function → The outer function ‘decorator’ takes a function as an argument (input) and returns the inner function object, that’s the only job of the outer function. Note that we are not calling functions while returning, we are just returning function objects, however, you can call it if you like to.
Inner Function → Now let’s take a look at the inner function which is doing the actual job. So, it’s just printing a string along with calling the function a decorator got as an input.
It’s as simple as that, did you find anything complex here, I hope you don’t. But In case you did, then the comment section is yours, just put your question over there and I will try my best to answer it.
Using Decorator with “@” syntax
Instead of assigning a function to a variable, passing its value, and then calling the function with that variable, we can use python simplified syntax. The thing we need to do is to just put “@decorator name” above our original function. And because of that, we don’t even need to call the decorator function, we can directly call our actual function, let’s see with the example
Using Decorator on function which takes Parameter
Okay, that was a simple function but what if you have a function that also takes arguments. Let’s see that
So, here we have a little bit modified version of the previous example, instead of printing a pre-defined name, we are now taking the name as an argument
Now to our decorator function, we made very subtle changes
How does it work?
As we know our outer function just takes a function and return function, so it’s still the same as it was. The changes we made are only in the inner function since our original function is taking argument we added parameter on an inner function which we are passing as an argument to our original function, which we are calling here “print(“Mr.”, func(name))”).
Can Decorators have its own parameter?
We show how we can use a decorator if a function takes an argument, but is that possible that a decorator itself can take a parameter. Yes, it is, to show an example let’s say instead of prefixing name with “Mr.” by default I want to let the user decide what they want to prefix their name with. Or in simple words, we want to pass an argument to a decorator.
So, let’s see how we can do that
Decorator Chain
Till now we saw, what, why, and how of decorators, but do you know we can use multiple decorators on a single function at once, how? Let’s see that!
Okay so, first we had a function which just prints our name then we modified its output by adding ‘Mr.’ to the output so, next our plan is to prefix our result with “Hi” so our final result will look something like this “Hi, Mr. John” from “Mr. John”.
So lets start by creating our two decorator function, one for prefixing “Mr.” and other for prefixing “Hi, ” at the beginning.
Okay now it’s time to use both decorators, I will be showing this in two ways
I am doing this to show you how it’s calling each other
- Our old styles (without ‘@’ syntax)
- New style (with ‘@’ syntax)
So, this was all about decorator if you want to read in more details then you can visit here. I hope you liked this, if you did then pls comment below your thought about decorator and do share it with your squad :D.
Data Scientist with 3+ years of experience in building data-intensive applications in diverse industries. Proficient in predictive modeling, computer vision, natural language processing, data visualization etc. Aside from being a data scientist, I am also a blogger and photographer.