Ticker

6/recent/ticker-posts

Python: Function Decorators

Decorator is a function that can take a function as argument and extend its functionality and returns modified function with extended functionality.

Function Decorators

The main objective of decorator functions is we can extend the functionality of existing 

functions without modifies that function.

1) def wish(name): 
2) print("Hello",name,"Good Morning") 

This function can always print same output for any name

Hello Durga Good Morning
Hello Ravi Good Morning
Hello Sunny Good Morning

But we want to modify this function to provide different message if name is Sunny. We can do this without touching wish() function by using decorator.

Eg:

1) def decor(func): 
2) def inner(name): 
3) if name=="Sunny": 
4) print("Hello Sunny Bad Morning") 
5) else: 
6) func(name) 
7) return inner 
8)
9) @decor 
10) def wish(name): 
11) print("Hello",name,"Good Morning") 
12) 
13) wish("Durga") 
14) wish("Ravi") 
15) wish("Sunny") 
16) 
17) Output
18) Hello Durga Good Morning 
19) Hello Ravi Good Morning 
20) Hello Sunny Bad Morning 

In the above program whenever we call wish() function automatically decor function will be executed.

Decorator Chaining

We can define multiple decorators for the same function and all these decorators will form Decorator Chaining.

Eg:

@decor1
@decor
def num():

For num() function we are applying 2 decorator functions. First inner decorator will work and then outer decorator.

Eg:

1) def decor1(func): 
2) def inner(): 
3) x=func() 
4) return x*x 
5) return inner 
6) 
7) def decor(func): 
8) def inner(): 
9) x=func() 
10) return 2*x 
11) return inner 
12)
13) @decor1 
14) @decor 
15) def num(): 
16) return 10 
17) 
18) print(num())

Generators

Generator is a function which is responsible to generate a sequence of values.

We can write generator functions just like ordinary functions, but it uses yield keyword to return values.

Generators

Eg 1:

1) def mygen(): 
2) yield 'A' 
3) yield 'B' 
4) yield 'C' 
5) 
6) g=mygen() 
7) print(type(g)) 
8) 
9) print(next(g)) 
10) print(next(g)) 
11) print(next(g)) 
12) print(next(g)) 
13) 
14) Output
15) <class 'generator'> 
16) A 
17) B 
18) C 
19) Traceback (most recent call last): 
20) File "test.py", line 12, in <module> 
21) print(next(g)) 
22) StopIteration

Advantages of Generator Functions:

  1. when compared with class level iterators, generators are very easy to use
  2. Improves memory utilization and performance.
  3. Generators are best suitable for reading data from large number of large files
  4. Generators work great for web scraping and crawling.

Generators vs Normal Collections wrt performance:

1) import random 
2) import time 
3) 
4) names = ['Sunny','Bunny','Chinny','Vinny'] 
5) subjects = ['Python','Java','Blockchain'] 
6) 
7) def people_list(num_people): 
8) results = [] 
9) for i in range(num_people): 
10) person = { 
11) 'id':i, 
12) 'name': random.choice(names), 
13) 'subject':random.choice(subjects) 
14) } 
15) results.append(person) 
16) return results 
17) 
18) def people_generator(num_people): 
19) for i in range(num_people): 
20) person = { 
21) 'id':i, 
22) 'name': random.choice(names), 
23) 'major':random.choice(subjects) 
24) } 
25) yield person 
26) 
27) '''''t1 = time.clock()
28) people = people_list(10000000)
29) t2 = time.clock()''' 
30) 
31) t1 = time.clock() 
32) people = people_generator(10000000) 
33) t2 = time.clock() 
34) 
35) print('Took {}'.format(t2-t1)) 

Generators vs Normal Collections wrt Memory Utilization:

Normal Collection:

l=[x*x for x in range(10000000000000000)]
print(l[0])

We will get MemoryError in this case because all these values are required to store in the memory.

Generators:

g=(x*x for x in range(10000000000000000))
print(next(g))

Output: 0
We won't get any MemoryError because the values won't be stored at the beginning

"Python Function Decorators"

"Python Function Decorators With Arguments"

"Python Multiple Decorators On Function"

"Python Two Decorators On One Function"

"Python Get Decorators Of Function"

"Python Can A Function Have Multiple Decorators"

"Function Decorators In Python 3"

"Python Decorators Get Function Name"

"Python Multiple Function Decorators"

"Python Get Function Decorators"