[Python-ideas] generator.close

Matt Joiner anacrolix at gmail.com
Wed Apr 11 13:28:18 CEST 2012


You make an excellent point. I'm inclined to agree with you. Cheers
On Apr 11, 2012 6:50 PM, "Jacob Holm" <jh at improva.dk> wrote:

> Hello Matt
>
> On 04/11/2012 11:38 AM, Matt Joiner wrote:
>
>> Why can't generator.close() return the value if a StopIteration is raised?
>>
>> The PEPs mentioned that it was proposed before, but I can't find any
>> definitive reason, and it's terribly convenient if it does.
>>
>>
> What should be returned when you call close on an already-exhausted
> generator?
>
> You can't return the value of the final StopIteration unless you arrange
> to have that value stored somewhere.  Storing the value was deemed
> undesireable by the powers that be.
>
> The alternative is to return None if the generator is already exhausted.
>  That would work, but severely reduces the usefulness of the change.
>
> If you don't care about the performance of yield-from, it is quite easy to
> write a class you can use to wrap your generator-iterators and get the
> desired result (see untested example below).
>
>
> - Jacob
>
>
> import functools
>
> class generator_result_wrapper(**object):
>    __slots__ = ('_it', '_result')
>
>    def __init__(self, it):
>        self._it = it
>
>    def __iter__(self):
>        return self
>
>    def next(self):
>        try:
>            return self._it.next()
>        except StopIteration as e:
>            self._result = e.result
>            raise
>
>    def send(self, value):
>        try:
>            return self._it.send(value)
>        except StopIteration as e:
>            self._result = e.result
>            raise
>
>    def throw(self, *args, **kwargs):
>        try:
>            return self._it.throw(*args, **kwargs)
>        except StopIteration as e:
>            self._result = e.result
>            raise
>
>    def close(self):
>        try:
>            return self._result
>        except AttributeError:
>            pass
>        try:
>            self._it.throw(GeneratorExit)
>        except StopIteration as e:
>            self._result = e.result
>            return self._result
>        except GeneratorExit:
>            pass
>
> def close_result(func):
>    @functools.wraps(func)
>    def factory(*args, **kwargs):
>        return generator_result_wrapper(func(***args, **kwargs))
>    return factory
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20120411/1f767952/attachment.html>


More information about the Python-ideas mailing list