Python decorators are considered as one of the very advanced and very useful concepts.
In this tutorial, I will explain Python decorators with examples. Going through this tutorial, you will learn to implement Python decorators and how it can be very useful in your project.
Table of Contents
This is one of the very popular Python interview questions asked in the IT job interviews.
Python decorators is a technique for changing the behavior of an existing function without changing actual code inside the function.
Even though we are changing the behavior of the function, there should not have any change in the function definition and function call.
It means…
Python has a special mechanism called Python decorators to change the behavior of the existing function.
It might be a bit confusing to you. Let’s go with an example.
How does Python Decorator work?
Let’s start with a simple Python function code.
def myFunc(): print("Hello, World!") myFunc()
Output:
Hello, World!
This is the basic Python program to implement a Python function. If you are new to Python programming, check basic Python code syntax.
Now consider a function that you want to wrap inside another function (called decorator).
It is similar to the technique of wrapping gifts inside flashy decorative papers.
Let’s see how it can be implemented in Python.
We know, that everything in Python is an object including the Python function. It means, we can pass the function object as an argument to another function. By default, the function name works as a function object.
We can write one Python function inside another function.
def myWrapper(func): def myInnerFunc(): print("Inside wrapper.") func() return myInnerFunc def myFunc(): print("Hello, World!") c=myWrapper(myFunc) c()
Output:
Inside wrapper. Hello, World!
Here we are passing the function (myFunc
) as a parameter to the wrapper function (myWapper
).
This is how it works.
myWrapper
has an inner function which calls the actual function (myFunc
).myFunc
).myWrapper
returns the inner function object.Note: When you write function name without brackets, it acts as a function object and it does not call function. The function gets called only when there is a function name (object) followed by brackets “()”.
If you compare the above two programs, you have changed the behavior of the original function. You can see the difference in the output.
We have fulfilled the first criteria of not changing code inside the function.
But the function call has changed
from
myFunc()
to
c=myWrapper(myFunc) c()
This does not fulfill our second criteria.
Here is the use of Python decorators.
def myWrapper(func): def myInnerFunc(): print("Inside wrapper.") func() return myInnerFunc @myWrapper def myFunc(): print("Hello, World!") myFunc()
Output:
Inside wrapper. Hello, World!
Python decorator name (@myWrapper
) is specified above the actual function definition. (2)
How does the Python decorator program execute?
Below are the steps of execution.
This is a simple Python decorator example. You can also pass the arguments to the Python decorators.
Many get confused decorators with the monkey patching techniques in Python. Two are the different things.
Original Function to add two numbers.
def addTwoNumbers(a, b): c=a+b return c c=addTwoNumber(4, 5) print("Addition of two numbers=", c)
Output:
Addition of two numbers=9
Now our aim is to modify the behavior of addTwoNumbers()
without changing function definition and function call.
What function behavior do we want to change?
We want addTwoNumbers
function should calculate the sum of the square of two numbers instead of the sum of two numbers.
Here is a simple decorator to change the behavior of the existing function.
def decorateFun(func): def sumOfSquare(x, y): return func(x**2, y**2) return sumOfSquare @decorateFun def addTwoNumbers(a, b): c = a+b return c c = addTwoNumbers(4,5) print("Addition of two numbers=", c)
Output:
Addition of two numbers=41
The below simple program is equivalent to the above decorator example. Here we are changing the function call.
def decorateFun(func): def sumOfSquare(x, y): return func(x**2, y**2) return sumOfSquare def addTwoNumbers(a, b): c = a+b return c obj=decorateFun(addTwoNumbers) c=obj(4,5) print("Addition of square of two numbers=", c)
Output:
Addition of square of two numbers=41
Note: The number of arguments to the function inside the decorators should be the same as the number of arguments to the actual function.
Suppose you are working on a project. You are asked to make the changes in a certain complex function.
If you are making changes in already tested and robust functions, you can not deny the possibility of breaking functionality.
A better way is to use Python decorators.
You can also pass the arguments to the decorators. You can modify these arguments inside the decorators before passing them to the original function.
This is all about Python decorators explained with examples. If you have any questions, ask in the comment section below.
After decorators, learn lambda function which is another advance topic in Python programming.
Happy Pythoning!
Mr. Chaudhari
c=obj(4,5) give a result 881 ((4^2)^2+(5^2)^2)
Alas, It gives a result 41 (4^2+5^2). You are calculating power twice which is not correct.
Great and more than clear explanation. Many thanks!
I’m glad as a Python fan finds it helpful. Next time I would love to see your name. 😀 Good day!
Great explanations, thanks so much as you have given much more clarity than previous articles I’ve read.
You’re welcome! I hope you enjoy referring to my other tutorials as well.