An Introduction to Decorators in Python

Python decorators allow us to change the behavior of a function without changing the function itself. Suppose we have a function which returns a text. Now we want the length of the text also without modifying the function. In this case we can do it using a wrapper function. Let’s see the code…

Let’s explain the above code first. Here message is the original function which returns a text message. Then length_wrapper is defined, it takes a function as its parameter and returns inner_function. When inner_function is called, it can access the original function message, passed through length_wrapper.

The inner_function is called nested function as it is defined inside another function.

But we can do the same job without using this nested function only through length_wrapper as the following code:

Let’s talk about the necessity of inner_function. In our present scenario the original function message does not take any parameter. But in arbitrary cases a function can take a parameter. Suppose message takes a parameter name and it is placed in the returned text.

Now message is defined as :

In this case we need the inner_function, otherwise we can’t pass the name parameter value to the message function. Let’s redefine the length_wrapper function as following:

There is a change in inner_function. This time we consider a parameter name. Now look how the functions are called one by one.

First we call the function length_wrapper with the parameter value message, it returns the inner_function, so the variable greet is a reference to inner_function. As inner_function takes the parameter name, we have passed the value “Jack” to greet and this “Jack” is passed to message when greet is executed. As a result we got — (‘Jack,Welcome to Python Decorators’, 33)

The function length_wrapper is called the decorator function. But this is not the proper way to call a decorator function. In order to apply a decorator function we have to mention a syntax @decorator_function_name, then define the original function as follows:

Here we have called the message function and printed the result, the output will be as (‘Jack,Welcome to Python Decorators’, 33), apparently the decorator function length_wrapper is applied to the message function, though we have not called length_wrapper anywhere.

Now we will see how to apply multiple decorator on a function. Let’s say we want the text message in upper case and its length. Earlier we applied a decorator for getting the length, now we will make a decorator to get the text message in uppercase.

Here we have defined a new decorator to_upper to get the message in upper case. Finally two decorators- to_upper, length_wrapper are applied on the message function. In such a case we need to take care of the order of the decorators here first to_upper is applied and the length_wrapper. If we want to call the decorators another way we need to redefine the to_upper decorator accordingly.

Now we will see the application of function decorator over a class, more precisely over a method of a class. Let’s define a class …

Here we have defined a class Person with two attributes height and weight and inside the class a method get_BMI is defined to get the BMI. Later we created an object p1 of type Person with height 5.5 feet and weight 65 kg. Then called the method get_BMI, it will print 23.13.

Now we want more information from the method get_BMI. We want to know whether the person is underweight, healthy weight, overweight or obesity and we will do it without changing the code of get_BMI method, we will do it using a decorator function. Let’s write the code …

Here we have defined a function weight_status, that takes the get_BMI method as input. get_BMI is called inside the nested function inner. One thing to notice, we have passed a parameter x to the function inner, which is equivalent to self of the method get_BMI. Now based on the bmi value inner function returns the bmi as well as the weight status. Inside the class Person, we have considered weight_status as a decorator for the method get_BMI.

At the end we have created an object of type Person with height 5.5 feet and weight 65 kg and then called the get_BMI method. This time it will print the result as “BMI : 23.13, Weight Status : Healthy Weight”.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store