This code is practical mainly in the trivial sense that it runs to completion.
# -*- coding: utf-8 -*-
"""
Created on Sun Jan 3 13:51:20 2016
@author: kurner
"""
import itertools
def assemble():
drv = yield None
drv.result = 1
drv = yield drv
drv.result += 1
drv.name = "Alvin"
drv = yield drv
drv.result += 1
drv.color = "Red"
drv = yield drv
drv.result += 1
drv.age = 100
return drv
class Driver:
def __init__(self, g):
self.g = g
self.g.send(None) # primed
self.counter = 1
def go(self):
while True:
try:
self.counter *= 10
self = self.g.send(self)
except StopIteration as exc:
return exc.args[0].__dict__
d = Driver(assemble())
r = d.go()
print(r)
Console output:
{'name': 'Alvin', 'color': 'Red', 'age': 100, 'counter': 10000, 'g': <generator object assemble at 0x110078af0>, 'result': 4}
The tractor classes I posted earlier should more properly by referred to as co-routines, as they were driven by a "tick" loop. Python itself is growing more powerful in this area.
What stands out about assemble() is it has yields, so is clearly a generator, but also it returns, and the StopIteration value is not only recoverable, but what we expect more generally from a 'yield from'.