Send method of generator iterators

Overview:

  • The yield statement returns a value back to the caller and gets suspended. 

  • The send() method, sends values into the current yield statement which is in suspended state, resumes the generator function and returns the values from the next yield.

  • The new values sent to the yield as it resumes should be assigned to variables in order to use them. If not assigned, the values are simply lost.

  • In the Python statement below, the values sent by send() are recieved by the variables in the yield expression, which are assigned further to use them inside the generator function. Without this assignment, the values sent by send() are lost.  
a,b = yield a, b
  • The statement below does not store the values sent by send(). The send() does not work like, the variables used in the yield are replaced with the values sent by send() within the whole scope of the generator function. Explicit storage of values from yield is essential.
yield a, b

Example:

# Define a generator function
def genfun():
    a = 10
    b = 20
    c = 100

    while(a > 0):
        a = a - 1
        b = b - 1 

        print("####Inside gen() - begin####")
        print(a)
        print(b)
        print(c)
        print("####Inside gen() - end####")
        print("Generator Just before suspend")
        a,b = yield a, b # yield got values from send and saving it
        #yield  a, b # yield gets values from send but not saved  
        print("Generator resumed")

# Create a generator iterator
geniter = genfun()
print(type(geniter))

# Start the generator
print(geniter.send(None))

print("Callee doing something else - Gen still frozen")
print("Callee doing still more - Gen frozen all the time")

# Send values to generator as packed in a tuple
# The tuple is unpacked inside the generator
# and values are assigned to variables specified in
# the yield
print(geniter.send((30, 40)))
#print(geniter.send((40, 50)))

# Uncommenting the print below will lead to,
#    a,b = yield a, b
# ValueError: not enough values to unpack (expected 2, got 1)
# print(geniter.send((30,)))

# Uncommenting the print below will lead to,
#    a,b = yield a, b
#ValueError: too many values to unpack (expected 2)
#print(geniter.send((40, 50, 60)))

 

Output:

<class 'generator'>

####Inside gen() - begin####

9

19

100

####Inside gen() - end####

Generator Just before suspend

(9, 19)

Callee doing something else - Gen still frozen

Callee doing still more - Gen frozen all the time

Generator resumed

####Inside gen() - begin####

29

39

100

####Inside gen() - end####

Generator Just before suspend

(29, 39)

 


Copyright 2024 © pythontic.com