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_2Note: 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 functionComplete 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_2def test_2()print("Decorated your function")test_1()def test_1()print("Hello World")Output:
Decorated your function
Hello WorldSometimes 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 handlerNow, it’s time to call our function addition()
addition(4,6)
addition(4,-6)Output:
10
Invalid valuesWe 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 rangedAnd 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 rangeNote: 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 valuesSometimes 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 Argsdef 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 ArgsHelp us improve this content by editing this page on GitHub