Generators in Python are like ordinary function the difference that it contains yield statement instead of return. Furthermore, when a function encounters an yield statement it pauses execution of function and saves the state of the function.
And when function is called again it starts from the next statement where it was paused. See the example below
def genfun(): i=1 print("This is the first __next__() call") yield i+1 print("This is the second __next__() call") yield i+2 print("This is the second __next__() call") yield i+3 genobj=genfun() a=genobj.__next__() # First time genfun() is called b=genobj.__next__() # Second time genfun() is called c=genobj.__next__() # Third time genfun() is called print(a) print(b) print(c)
Output:
This is the first __next__() call
This is the second __next__() call
This is the second __next__() call
2
3
4
In the above program a generator function genfun() is defined which contains three yield statements.
First of all statement genobj=genfun() creates a generator object, and when it calls first time __next__() function it invokes genfun() and it pauses execution of genfun() and saves the state of the genfun(). And when it calls genfun() second time using genfun.__next__() statement it invokes genfun(), again but not from the beginning it will start where it was paused. This will also be repeated for the third time.