logo-StatusNeo
d

WE ARE EXPERTS IN TECHNOLOGY

Let’s Work Together

decorators-in-python

StatusNeo

Decorators in Python for Humans !!

A quick introduction to Decorators in Python and how to use them.

Decorators in Python

What comes to your mind when you hear the term decorator? Okay, let’s imagine the following to get a better understanding

1. It’s your birthday and a friend gives you a book.

2. Now another, friend also gives you a book but decorates it with a beautiful gift wrap and write your name on it with a glitter along with a note of blessings Now, if you look closely, the gift didn’t change in 2nd case, but your experience became slightly better. The good thing is that the basic meaning of decoration is not very different when it comes to Python as well. What that means is in Python, decorators are used to add some functionality to a function without directly changing the syntax of that function. Now as we take our discussion ahead, do keep in mind your 2nd friend, who gifted you the same book ( book remains same ) but with added decoration.

Pre-requisites

In this section, we’re going to cover some of the important pre-requisites concepts which are essential before we jump to the concept of decorators.

Functions are objects in Python

In the Python language, everything including the primitive types like int, float, strings, functions etc all are objects. It’s interesting to know that even the function itself is an object but knowing it we can easily do the following:

  1. Assign functions to variables
def gift():
    print("Its a book")
a = gift 
a() 
# prints: It's a gift 


2. Pass functions as parameters

def book():
    return 'Book'
def card():
    return "Card"
def gift(item, pack):
    packed_gift = item() + 'packed in' + pack 
	return packed_gift 
a = gift(book, "red") 
b = gift(card, "blue")
a()
# prints: book packed in red 
b()
# print book packed in blue 


Return functions from other functions
def book():
    return "Book"
def card():
    return "Card"
def gift_shop(item):
    inventory = {
		"card": card,
		"book": book
	}
	return inventory.get(item)
item = gift_shop('card')
item()
# prints: Card 
item = gift_shop('book')
item()
# prints: Book 

Python Decorators

Based on the examples above, we’ll see how Python utilizes the above features in order to add functionality to a function during runtime. First let’s look at the syntax of the Decorators in the next section and then we’ll see some examples in the later sections.

Decorator Syntax

The decorator syntax works as follows:

  1. Define a function A
  2. Pass it to another function B ( called decorator function )
  3. There’s a third function C which is defined inside of the decorator function, it can play with the variables of the ‘A’ function and then it will return the function A with original call
  4. This third function ‘C’ is where we can add whatever functionality we want to add

So the syntax in general looks like below:

def B(A):
    def C(a,b):
	    # a, b is the data of A 
		# add whatever functionality needs to be added here 
		# return the original function with original vars 
		return A(a,b)
	# return this inner function 
	# so when it is called, first it will execute the added functionality 
	# then it will call the function 
	return C

Example of Decorators without @

Now that we’ve build a solid understanding of how exactly decorators work and how they’re built, let’s create our first decorator. Hope that by now you’ve understood the concept and are excited to create your first decorator. So going back to our gift example, let’s decorate our gift with the help of decorators.

def item(num):
    inventory = {
		1: "book",
		2: "card"
	}
	return inventory[num] 
# wrap_it is our decorator 
# pack is where we add functionality to our original function 
# so what we're going to do is we're going to add some surprise by 
# swapping the card and book gift on the fly 
def wrap_it(func):
    def pack(num):
	    if num == 1:
		    num = 2 
		else: 
		    num = 1 
	    return func(num)
	return pack 
get_gift = wrap_it(item) 
packed_book_gift = get_gift(1)
# should now return a card gift after decoration
packed_card_gift = get_gift(2)
# should now return a book gift after decoration 

Decorators with @ syntax

The good news is that if you’re reading this, you’ve already learnt the concept of decorators. And the better news is that, now that you understand the basic concept of decorators, there’s an interesting shortcut way to write the decorators in Python using the @ symbol. In most real life examples, this is the syntax you’ll encounter so it’s good to get used to it. So here let’s look at the above example again just with a different syntax.

# observe the syntax change in how we use wrap_it this time 
def wrap_it(func):
    def pack(num):
	    if num == 1:
		    num = 2 
		else: 
		    num = 1 
	    return func(num)
	return pack 
# using @ will also have a similar effect like above example 
@wrap_it
def item(num):
    inventory = {
		1: "book",
		2: "card"
	}
	return inventory[num] 
packed_card_gift = item(2)
# should now return a book gift after decoration 

Summary

In this article, we took a few steps to better understand what decorators are in a language comprehensible to most humans. In case you liked this approach of learning about decorators, don’t forget to share in your network.

Add Comment