×

Python Decorator

Python Decorator: A Decorator is an interesting feature of Python that helps the user design patterns and insert a new functionality to an existing object without making any modifications in its structure. Usually, we call Decorators before defining the function that we want to decorate. We will discuss a lot about the decorators and their uses in Python Programming. Moreover, this type programming is also known as metaprogramming because, in this programming, one part of the program is modified by another during the compilation time and vice versa.

The functions in Python are First-Class Object, which means they support various operations. For example - Being returned from a function passed as an argument, modified, assigned to a variable and many more. Let's start exploring how to implement decorators in the Python Programs and many in the following sections.

Prerequisites to learn Python decorators

Before we jump into Python decorators' depth, there are some fundamentals we must need to know.

Starting with the fact that everything in Python (Even the classes) are objects. The Names that we define works as identifiers that are bounded to these objects. There are no exceptions that even Functions are also objects (with attributes). We can bound different names to the same function object. The same is illustrated in the following example.

Example -

def initial(message):
     print(message)
 initial("Hello There!")
 final = initial
 final("Hello There!") 

The above snippet of code should produce an Output, as shown below:

Output:

Hello There!
Hello There!

As we can observe, we are getting the same result from both the functions, initial and final, respectively. And the name initial and final refers to the same function object.

Now, let’s explore a bit deeper into this section. We can also pass one function to another as an argument. This functionality can be seen in various functions such as filter, map and reduce in Python. Such functions are also known as higher-order functions as these functions take other functions as arguments. The same is demonstrated in the following example:

def increment(a):
     return a + 2
 def decrement(a):
     return a - 2
 def activate(function, a):
     res = function(a)
     return res 

The above function can be invoked using a python interpreter, as shown below:

activate(increment, 4)
 6
 activate(decrement, 4)
 2
 Moreover, a function can also return another function.
 def iscalled():
     def isreturned():
         print("Welcome to TutorialandExample.com")
     return isreturned
 its_new = iscalled()
 # Output "Welcome to TutorialandExample.com"
 its_new()
 Welcome to TutorialandExample.com 

Output:

In the above example, we can observe that a nested function, namely isreturned(), is defined and return each time we call iscalled().

Getting back to Python Decorators

First of all, the methods and functions are Callable because of their ability to be called. Any object can be termed as callable if it implements the special method called __call__(). Thus, we can say that a decorator is also a callable that helps return a callable.

More specifically, a decorator takes a function as input, adds some functionality to it and returns it. We can see the following example for more understanding.

def pretty(function):
     def inside():
         print("This function is decorated!!")
         function()
     return inside
 def the_ordinary():
     print("This is an ordinary function.")
 The above snippet of code should produce the following output once executed in the python interpreter.
 print(the_ordinary()) 

Output:

This is an ordinary function.

# Let’s start decorating this ordinary function
 the_pretty = pretty(the_ordinary)
 print(the_pretty()) 

Output:

This function is decorated!!

In the above example, we have to use the function pretty() as a decorator. In the assignment step:

the_pretty = pretty(the_ordinary)

We have decorated the function the_ordinary() function and give the name the_pretty() to the returned function.

As we can observe that the original function is decorated using the decorator function that added some new functionality to it. This is kind of similar to gift packaging. The decorator works as a wrapper. It does not alter the nature of the object that got decorated, i.e., the real gift inside. However, the present looks pretty now (since it got decorated).

Usually, a function is decorated and reassigned as follows:

the_ordinary = pretty(the_ordinary)

The syntax shown above is a common construct and can be easily simplified in Python.

This can be done using the @ symbol alongside the decorator function name and placing it above the function definition that is to be decorated. Let’s see the following example:

@pretty  
 def the_ordinary():      
 print("This is an ordinary function.")   

is equivalent to

def the_ordinary():      
 print("This is an ordinary function.")  
 the_ordinary = pretty(the_ordinary)  

The above example is simply a cube of syntactic sugar for implementing Python decorators.

Decorating Functions with Parameters

The decorator shown above was quite simple and usually worked with functions with no parameters. But how to decorate the functions that take in parameters such as:

def div(x, y):
    return x / y

The above function has two parameters, x and y. And we know that it will return an error if we pass in y as 0.

print(div(3,2))
 1.5
 print(div(4,0))
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "<stdin>", line 2, in div
 ZeroDivisionError: division by zero 

Now, we will be making a decorator for checking for this case that will cause the error.

def smart_div(function):
     def inside(x, y):
         print("Let's start dividing", x, "and", y)
         if y == 0:
             print("Ugh! Poor choice of numbers. This cannot divide.")
             return
         return function(x, y)
     return inside
 @smart_div
 def divide(x, y):
     print(x/y) 

Let’s try the above snippet of code and see the output we get:

Print(div(3,2))
 Let's start dividing 3 and 2
 1.5
 print(div(4,0))
 Let's start dividing 4 and 0
 Ugh! Poor choice of numbers. This cannot divide. 

As we can observe, the decorator function implementation will return none whenever the error persists. And Thus, we can decorate the functions with parameters.

Chaining Decorators in Python

We can chain multiple decorators in Python. This statement implies that we can decorate a function multiple times with the same or different decorators. All we need is to place the decorator above the chosen function. Here’s an example is shown below:

def inverted_commas(function):
     def inside(*first, **second):
         print("'" * 35)
         function(*first, **second)
         print("'" * 35)
     return inside
 def stars(function):
     def inside(*first, **second):
         print("*" * 35)
         function(*first, **second)
         print("*" * 35)
     return inside
 @inverted_commas
 @stars
 def the_printer(message):
     print(message)
 the_printer("WELCOME TO TUTORIALANDEXAMPLE.COM") 

The above snippet of code should produce an Output, as shown below:

'''''''''''''''''''''''''''''''''''
 ***********************************
 WELCOME TO TUTORIALANDEXAMPLE.COM
 ***********************************
 ''''''''''''''''''''''''''''''''''' 

The above syntax of

@inverted_commas
 @stars
 def the_printer(message):
     print(message) 

is equivalent to

def the_printer(message):
     print(message)
 the_printer = inverted_commas(stars(the_printer)) 

In addition to the above, one more factor affects the decorators' chaining. This factor is the order of chaining the decorators. If we had reversed the order as

@stars
 @inverted_commas
 def the_printer(message):
     print(message) 

The Output would be:

***********************************
 '''''''''''''''''''''''''''''''''''
 WELCOME TO TUTORIALANDEXAMPLE.COM
 '''''''''''''''''''''''''''''''''''
 *********************************** 

Related Topics

Python zip() Function

Python zip() Function The zip() function makes an iterator that aggregates elements from each of the iterables and returns an iterator of tuples. Syntax zip(*iterables) Parameter iterables: Iterator objects that will be joined together Return This function...

1 minute read.

Loan Calculator using PyQt5 in Python

In the following tutorial, we will learn how to build a Loan Calculator application using the PyQt5 library in the Python programming language. So, let's get started. Introduction to the code: The heading...

4 minutes read.

Find whether the given stringnumber is palindrome or not

Problem statement Sam is found of playing with strings. One day he thought of finding whether a string is a palindrome or not. He wanted to develop a computer process to...

2 minutes read.

Python String lower() method

Python String lower() method The string.lower() method in Python returns a string where all characters are lower case. Syntax string.lower() Parameter NA Return This method returns a string where all characters are lower case. Example 1 # Python...

1 minute read.

Python Bubble Sort

Bubble sort is one of the techniques used to sort the elements in lists in a certain order, either in ascending or descending order. It is called Bubble sort because...

4 minutes read.

Python Parallel Processing

By performing more jobs concurrently, your software may complete more tasks in a shorter amount of time. These aid in solving major issues. The following subjects will be covered in...

2 minutes read.

Best Way to Learn Python for Free

Python is a booming language these days. It has many applications for making code easier; it is also an open-source language. Learning Python is a step towards coding. Python gets...

5 minutes read.

Python Printf Style Formating

String objects have one special implicit activity: the % administrator (modulo). This is otherwise called the string designing or interjection administrator. Given design % values (where configuration is a string),...

3 minutes read.

Difference between For Loop and While Loop in Python

What is the “For” loop? The “For” Loop is a commonly used control structure in programming that allows us to repeat a set of actions multiple times. The “For” loop is...

3 minutes read.

Python program to count the number of a substring in a string

Python program to count the number of a substring in a string A part of the string is called a substring. This article explains the Python program to find how many...

1 minute read.

Python Keywords

If you are trying to learn a programming language, you need to have a basic idea of "What are keywords" and "How they are used". You can learn about keywords in...

7 minutes read.

Python bin() function

Python bin() function The bin() function in Python returns the binary version for the specified integer. Syntax bin(x) Parameter n: This parameter represents an integer or int value. Return This function returns a binary string for the specified integer...

1 minute read.

Python List copy() method

Python List copy () method The list.copy () method returns a shallow copy of the list. Syntax list.copy() Parameter NA Return This function returns the copy for the given list. Example 1 # Python program explaining # the list.copy() method # passing the...

1 minute read.

Notepad++ For Python

In this article, you are going to learn what notepad++ is and how it is integrated with python to use the python programming language. You can also learn how to...

4 minutes read.

Binary Search Visualization using Pygame in Python

A calculation like Binary Search is seen effectively by picturing. Here in this tutorial, a function that pictures the Binary Search Algorithm is carried out. The Graphical User’s Interface (GUI)...

15 minutes read.

Python Variables

Variables are one of the most important terms we should be familiar with if we want to be good programmers. In simpler words, we use variables to store a value....

4 minutes read.

An Introduction to Mocking in Python

Python Mocking is a testing library. It enables you to substitute portions of your system under test with fake(mock) objects and make assertions about how they were utilized.  The test is...

3 minutes read.

Python Lexicographic Order

Python lexicographic order Before we discuss the lexicographic order in Python, we should understandwhat is lexicographic order and sort according to lexicographic order. Lexicographic order In mathematics, the generalization of the alphabetical order...

5 minutes read.

How to run a Program in Python

How to run a Program in Python Writing a program in Python is an easy task, beginners who are ready to kickstart their career in the world of programming can create...

3 minutes read.

How to change the names of Columns in Python

Introduction To play with huge amounts of data, in Python we require a tool. The tool which is available in Python is Pandas. Pandas is an open-source library. It is used...

3 minutes read.