On Thu, Apr 2, 2009 at 5:35 PM, Ron Adam <rrr@ronadam.com> wrote:
Jacob Holm wrote:
That might be the prevailing wisdom concerning GeneratorExit, at least partly based on the fact that the only way to communicate anything useful out of a closing generator is to raise another exception. Thinking a bit about coroutines, it would be nice to use "send" for the normal communication and "close" to shut it down and getting a final result. Example:
def averager(): count = 0 sum = 0 while 1: try: val = (yield) except GeneratorExit: return sum/count else: sum += val count += 1
avg = averager() avg.next() # start coroutine avg.send(1.0) avg.send(2.0) print avg.close() # prints 1.5
To do something similar today requires either a custom exception, or the use of special values to tell the generator to yield the result. I find this version a lot cleaner.
This doesn't seem less cleaner than the above to me.
def averager(): sum = 0 count = 0 try: while 1: sum += yield count += 1 finally: yield sum / count
avg = averager() avg.next() avg.send(1.0) avg.send(2.0) print avg.next() # prints 1.5
But your version isn't clean -- it relies on "sum += yield" raising a TypeError when yield returns None (due to .next() being the same as .send(None)). That's not to say I like Jacob's version that much, but I now understand his use case. I note that Dave Beazley works around this carefully in his tutorial (dabeaz.com/coroutines/) by using examples that produce output on stdout -- and much later, in his multitasking schedule example, his trampoline actually interprets yielding a value that is neither a SystemCall instance nor a generator as a return from a generator. (This is similar to the abuse that your example is giving yield, actually.) I'll have to ponder this more. __________ PS. Somehow the headers in your email made my reply add this: Python-Ideas <public-python-ideas-+ZN9ApsXKcEdnm+yROfE0A@ciao.gmane.org>, Nick Coghlan <public-ncoghlan-Re5JQEeQqe8AvxtiuMwx3w@ciao.gmane.org> Whoever did that, and whatever they did to cause it, please don't do it again. -- --Guido van Rossum (home page: http://www.python.org/~guido/)