[Python-ideas] generator.close
Jacob Holm
jh at improva.dk
Wed Apr 11 12:50:28 CEST 2012
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
More information about the Python-ideas
mailing list