Have you ever heard about Gift wrappings? Exactly, those which we do on the presents to be gifted. Decorators in Python are nothing but the Gift Wrapping but for functions and classes. In this tutorial, we will deep dive into the implementation of decorators on functions. But before you get into the topic, you should have a proper understanding of functions in Python. Assuming that you have, let’s get started.
A decorator is nothing but a function that takes a function to be decorated as its parameter, and returns a function. A decorator is used to extend the functionality of a function by wrapping it in another function, i.e, The decorator function, without modifying the base function.
@decoration_function
def test_1():
print("Hello World")
The above function simply means,
test_1 = decoration_function(test_1)
Here, @decoration_function
denotes a decorator.
Now let’s define the decorator function decoration_function
.
def decoration_function(function_to_be_decorated):
def test_2():
print("Decorated your function")
function_to_be_decorated()
return test_2
Note: The decorator definition should be above the function_to_be_decorated
.
We are all done decorating our function test_1()
. Now, let’s try it out.
test_1() //Calling the function
Complete Code:
def decoration_function(function_to_be_decorated):
def test_2():
print("Decorated your function")
function_to_be_decorated()
return test_2
@decoration_function
def test_1():
print("Hello World")
test_1()
The sequence of execution is as follows:
decoration_function(test_1)
return test_2
def test_2()
print("Decorated your function")
test_1()
def test_1()
print("Hello World")
Output:
Decorated your function
Hello World
Sometimes we stumble upon situations where our function takes parameters, so let us consider a function addition()
which takes 2 integer parameters, a
and b
, and returns their sum.
@decorate_addition
def addition(a,b):
print(a+b)
Let us decorate the above function which handles situations where a
or b
is a negative integer.
def decorate_addition(function):
def handler(a,b):
if(a < 0 or b < 0):
print("Invalid values")
return
return function(a,b)
return handler
Now, it’s time to call our function addition()
addition(4,6)
addition(4,-6)
Output:
10
Invalid values
We can also add multiple decorators to our function. So let’s add another decorator on the above addition()
function.
def max_range(function):
def ranged(a,b):
if(a > 100 or b > 100):
print("Values out of range")
return
return function(a,b)
return ranged
And modifying our decorators by adding @max_range
,
@max_range
@decorate_addition
def addition(a,b):
print(a+b)
Let’s call our function again,
addition(400,-6)
Output:
Values out of range
Note: The sequence of decorators above addition()
matters. It is executed from top to bottom. For instance,
@decorate_addition
@max_range
def addition(a,b):
print(a+b)
Let’s call our function again,
addition(400,-6)
Output:
Invalid values
Sometimes we come across situations where we have to pass multiple arguments, positional, or keyword. Python provides us with *args (tuple for positional arguments) and **kwargs (dictionary for keyword arguments).
def multiple_args(function_to_be_decorated):
def internal(*args,**kwargs):
print("Positional arguments", args)
print("Keyword arguments", kwargs)
function_to_be_decorated(*args)
return internal
@multiple_args
def test_fun():
print("Keyword Args")
test_fun(name="TutsWiki", language="Python")
Output:
Positional arguments ()
Keyword arguments {'language': 'Python', 'name': 'TutsWiki'}
Keyword Args
def multiple_args(function_to_be_decorated):
def internal(*args,**kwargs):
print("Positional arguments", args)
print("Keyword arguments", kwargs)
function_to_be_decorated(*args)
return internal
@multiple_args
def test_fun(a,b):
print("Positional Args")
test_fun(1,2)
Output:
Positional arguments (1, 2)
Keyword arguments {}
Positional Args
Help us improve this content by editing this page on GitHub