I don't understand generator.send()

Chris Rebert crebert at ucsd.edu
Sat May 14 20:47:00 EDT 2011


On Sat, May 14, 2011 at 5:08 PM, Victor Eijkhout <see at sig.for.address> wrote:
> #! /usr/bin/env python
>
> def ints():
>    i=0
>    while True:
>        yield i
>        i += 1
>
> gen = ints()
> while True:
>    i = gen.next()
>    print i
>    if i==5:
>        r = gen.send(2)
>        print "return:",r
>    if i>10:
>        break
>
> I thought the send call would push the value "2" at the front of the
> queue. Instead it coughs up the 2, which seems senseless to me.
>
> 1/ How should I view the send call? I'm reading the manual and dont' get
> it

`yield` is an expression. Within the generator, the result of that
expression is [, ignoring the complications of .throw() etc.,] the
argument to .send(). You're currently using `yield` only as a
statement, so it's no wonder you're not quite understanding .send(). I
think this example should clarify things somewhat:

>>> def example(start):
...     i = ord(start)
...     while True:
...         sent = (yield chr(i)) # Note use of yield as expression
...         print('was sent', sent)
...         i += 1
...
>>> g = example('a')
>>> g.send(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't send non-None value to a just-started generator
>>> # Ok, so we can't send something back to `yield`
>>> # until we hit the first `yield`.
>>> g.send(None) # Follow the error message's advice
'a'
>>> g.send(3) # Let's try again now.
was sent 3
'b'
>>> g.send(5)
was sent 5
'c'
>>> g.send(9)
was sent 9
'd'
>>>

Cheers,
Chris
--
http://rebertia.com



More information about the Python-list mailing list