In addition to receiving values from a generator, it is possible to send an object to a generator using the
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
yieldstatement, and returns the value of
totalat that point, which is 0. The execution of the generator suspends at this point.
generator.send(x), the interpreter takes the argument
xand makes it the return value of the last
yieldstatement, 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
Noneto the generator. There is nothing special about
None, however, this example uses
Noneas a special value to ask the generator to stop.