Python Coroutines
David Beazley's Curious Course on Coroutines and Concurrency in Python is the best coroutine tutorial I've seen.
It makes an essential distinction between generators, from which you pull data, like this:
def squares():
for i in range(10):
yield i * i # send data
for j in squares():
print j
... and coroutines, through which you push data, like this:
def line_printer():
buf = ''
try:
while True:
buf += (yield) # receive data
parts = buf.split('\n')
if len(parts) > 1:
# We've received 1 or more new lines, print them
for part in parts[:-1]: print part
buf = parts[-1]
except GeneratorExit:
# Someone has called close() on this generator, print
# the last of the buffer
if buf: print buf
# push random chars, and sometimes newlines, into the coroutine
import random
coroutine = line_printer()
coroutine.next() # start coroutine
for i in range(1000):
random_char = chr(random.randint(ord('a'), ord('z') + 1))
if ord(random_char) > ord('z'):
random_char = '\n'
coroutine.send(random_char)
coroutine.close()
I plan to spend a lot of time with coroutines in the next few months, in particular seeing how they can simplify coding in asynchronous Python web frameworks.