Python Generators and Decorators

Python Generator

The python generators provide a simple method of generating iterators. These generators, rather than restoring the function from the return statement, utilize the “yield “keyword. Those are the generator variant of the record apprehensions. If the function includes a minimum one “yield” declaration, it develops into a generator function. They both the yield and return will restore a few values from the function.

Why python uses generators?

Python uses the idea of generators because of a few reasons.

  1. Simple to execute: We can run the generators rapidly, and transparently. It significantly decreases the program when contrasted to iterators. This is therefore dissimilar to iterators, and generators can call the operations like iter () and next () necessarily.
  2. Memory efficient: Before the returning of the outcome, a regular function generates a whole series of memory. But if the element number is high memory turns into a pointless excess. In generators, the series is memory friendly because it generates one element at a time.
  3. Infinite stream representation: Generators are an excellent medium to represent infinite steam information. Therefore the generators produce just one at a time, and unlimited streams can be saved in the memory.
Example

def gen():

 

a = 10

 

print(‘This is printed first’)

 

# Generator function includes yield statements

 

yield a

 

a += 1

 

print(‘This is printed second’)

 

yield a

 

a += 1

 

print (‘This is printed at the end’)

 

Yield a

 

# using for loop

 

For i in gen ():

 

Print(i)


Decorators

A decorator is a python feature that adds functionality to the current program. This is also known as Metaprogramming. It was said because it was attempting to modify one or more programming method at compile time. Decorators enable us to steal up another function to expand the behaviour of other function.

In decorators, functions are taken as the parameters in another function. Furthermore, within the wrapper operation, we can call the decorators. Using decorator’s ideas is simple, but the execution of these decorators is a bit difficult.

Decorator with parameters

A decorator takes only one parameter: the function should be decorated. It’s inaccessible to pass other parameters.

Example

def decoratorfactory(message):

 

def decorator(func):

 

def wrapped_func(*args, **kwargs):

 

print(‘The decorator needs to tell us: {}’.format(message))

 

return func(*args, **kwargs)

 

return wrapped_func

 

return decorator

 

@decoratorfactory(‘Hello World’)

 

def test():

 

pass

 

test()


Decorator classes

def decoratorfactory(*decorator_args, **decorator_kwargs):

 

class Decorator(object):

 

def __init__(self, func):

 

self.func = func

 

def __call__(self, *args, **kwargs):

 

print(‘Inside the decorator with arguments {}’.format(decorator_args))

 

return self.func(*args, **kwargs)

 

return Decorator

 

@decoratorfactory(10)

 

def test():

 

pass

 

test()


How to generate a singleton class with a decorator?

The singleton is a design that confines the launch of a class to one instance/object. Utilizing a decorator, we can characterize a class as a singleton by driving the class to either restore a current instance of the class or generate a new instance (if it doesn’t happen).

Example

def singleton(cls):

 

instance = [None]

 

def wrapper(*args, **kwargs):

 

if instance[0] is None:

 

instance[0] = cls(*args, **kwargs)

 

return instance[0]

 

return wrapper


This decorator can be inserted to some class declaration and should create confident that at last one instance of the class is generated. Some subsequent calls will restore the already current class instance.

Example

@singleton

 

class SomeSingletonClass:

 

x = 2

 

def __init__(self):

 

print(“Created!”)

 

instance = SomeSingletonClass() # prints: Created!

 

instance = SomeSingletonClass() # doesn’t print anything

 

print(instance.x)

 

instance.x = 3

 

print(SomeSingletonClass().x)


What is Iterators?

The iterable is an item that can restore an iterator. Some object with the state that has an __iter__ technique and converts an iterator is iterable. It can additionally be an object without a state that executes a __getitem__ method. – The technique can take indices (beginning from zero) and increase an IndexError when the indices are no higher valid.

Python str object is an instance of a __getitem__ iterable.

An Iterator is an object that generates the following value in a series when we call following (*object*) on few object. Further, some object with a __next__ technique is an iterator. An iterator increases Stop Iteration after draining the iterator and cannot be recycled at this point.

Iterable classes:

Iterable classes define an __iter__ and a __next__ method.

 

Example of an iterable class:

 

class MyIterable:

 

def __iter__(self):

 

return self

 

def __next__(self):

 

#code

 

#Classic iterable object in older versions of python, __getitem__ is still supported.

 

class MySequence:

 

def __getitem__(self, index):

 

if (condition):

 

raise IndexError

 

return (item)

 

#Can produce a plain `iterator` instance by using iter(MySequence())


Extract values one by one

It begins with iter() construct-in to get iterator over iterable and utilize next() to get components one by one until StopIteration is increased indicating the last:

 

s = {1, 2} # or list or generator or even iterator

 

i = iter(s) # get iterator

 

a = next(i) # a = 1

 

b = next(i) # b = 2

 

c = next(i) # raises StopIteration


Iterating over whole iterable

s = {1, 2, 3}

 

# get each element in s

 

for a in s:

 

print a # prints 1, then 2, then 3

 

# replica into list

 

l1 = list(s) # l1 = [1, 2, 3]

 

# utilize list comprehension

 

l2 = [a * 2 for a in s if a > 2] # l2 = [6]


What can be iterable?

Iterable can be entity for which elements are get one by one, leading only. Built-in Python collections are iterable:

 

[1, 2, 3] # list, iterate over items

 

(1, 2, 3) # tuple

 

{1, 2, 3} # set

 

{1: 2, 3: 4} # dict, iterate over keys

 

Generators return iterables:

 

def lis(): # foo isn’t iterable yet…

 

yield 1

 

res = lis() # …but res already is

Enroll Yourself: Python Training



							
	                        

	                    

Copyright 1999- Ducat Creative, All rights reserved.