[Python-Dev] New PEP 342 suggestion: result() and allow "return with arguments" in generators (was Re: PEP 342 suggestion: start(), __call__() and unwind_call() methods)

Guido van Rossum guido at python.org
Sun Oct 9 16:46:09 CEST 2005


On 10/9/05, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Sometimes I miss the obvious. There's a *much*, *much* better place to store
> the return value of a generator than on the StopIteration exception that it
> raises when it finishes. Just save the return value in the *generator*.
>
> And then provide a method on generators that is the functional equivalent of:
>
>      def result():
>          # Finish the generator if it isn't finished already
>          for step in self:
>              pass
>          return self._result # Return the result saved when the block finished
>
> It doesn't matter that a for loop swallows the StopIteration exception any
> more, because the return value is retrieved directly from the generator.

Actually, I don't like this at all. It harks back to earlier proposals
where state was stored on the generator (e.g. PEP 288).

> I also like that this interface could still be used even if the work of
> getting the result is actually farmed off to a separate thread or process
> behind the scenes.

That seems an odd use case for generators, better addressed by
creating an explicit helper object when the need exists. I bet that
object will need to exist anyway to hold other information related to
the exchange of information between threads (like a lock or a Queue).

Looking at your example, I have to say that I find the trampoline
example from PEP 342 really hard to understand. It took me several
days to get it after Phillip first put it in the PEP, and that was
after having reconstructed the same functionality independently. (I
have plans to replace or augment it with a different set of examples,
but haven't gotten the time. Old story...) I don't think that
something like that ought to be motivating generator extensions. I
also think that using a thread for async I/O is the wrong approach --
if you wanted to use threads shou should be using threads and you
wouldn't be dealing with generators. There's a solution that uses
select() which can handle as many sockets as you want without threads
and without the clumsy polling ("is it ready yet? is it ready yet? is
it ready yet?").

I urge you to leave well enough alone. There's room for extensions
after people have built real systems with the raw material provided by
PEP 342 and 343.

--
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list