11

I'm studying in Python yield and find that yield is not only the way in which generators output a return value but also a way to put values into a generator. For example the following code

def f():
    print (yield),
    print 0,
    print (yield),
    print 1

g = f()
g.send(None)
g.send('x')
g.send('y')

In the global scope it sends value 'x', 'y' to the generator and thus in f it will output x 0 y 1. But I cannot understand

  • There are 2 yields but 3 sends. Why should it send None at the first time?
  • It throws a StopIteration at the last send. Is there any way to avoid this exception?

Could anyone please explain that? Thanks in advance.

Rafa Viotti
  • 9,998
  • 4
  • 42
  • 62
neuront
  • 9,312
  • 5
  • 42
  • 71

1 Answers1

11

From the documentation:

When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

As for the exception, you can't really avoid it. The generator throws this exception when it's done iterating, so instead of avoiding it, just catch it:

g = f()

try:
    g.send(None)
    g.send('x')
    g.send('y')
except StopIteration:
    print 'Done'
Blender
  • 289,723
  • 53
  • 439
  • 496
  • There is a way to avoid the exception. Put an extra `yield` at the end of the generator function. The generator will not close, but will eventually be garbage collected. – Rafa Viotti Oct 03 '15 at 17:27
  • g.send(None) makes no sense,although must be added – shenyan Feb 17 '17 at 08:27