Quick Contact

     

    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.