In addition to receiving values from a generator, it is possible to send an object to a generator using the send()
method.
def accumulator():
total = 0
value = None
while True:
# receive sent value
value = yield total
if value is None: break
# aggregate values
total += value
generator = accumulator()
# advance until the first "yield"
next(generator) # 0
# from this point on, the generator aggregates values
generator.send(1) # 1
generator.send(10) # 11
generator.send(100) # 111
# ...
# Calling next(generator) is equivalent to calling generator.send(None)
next(generator) # StopIteration
What happens here is the following:
next(generator)
, the program advances to the first yield
statement, and returns the value of total
at that point, which is 0. The execution of the generator suspends at this point.generator.send(x)
, the interpreter takes the argument x
and makes it the return value of the last yield
statement, which gets assigned to value
. The generator then proceeds as usual, until it yields the next value.next(generator)
, the program treats this as if you're sending None
to the generator. There is nothing special about None
, however, this example uses None
as a special value to ask the generator to stop.