Could someone help me understand what PEP479 is about? I was reading the doc and couldn't get my head around it.
The abstract says:
This PEP proposes a change to generators: when StopIteration is raised inside a generator, it is replaced it with RuntimeError. (More precisely, this happens when the exception is about to bubble out of the generator's stack frame.)
So for example, does a loop like so still work?
it = iter([1,2,3])
try:
i = next(it)
while True:
i = next(it)
except StopIteration:
pass
Or does it mean that if I have a generator definition like so:
def gen():
yield from range(5)
raise StopIteration
the StopIteration
is going to be replaced with RuntimeError
?
I would really appreciate if someone could shed some light on this.
Iterator in Python uses the two methods, i.e. iter() and next(). The next() method raises an StopIteration exception when the next() method is called manually. The best way to avoid this exception in Python is to use normal looping or use it as a normal iterator instead of writing the next() method again and again.
A yield point is reached, and the yielded value is returned. The frame is returned from; StopIteration is raised. An exception is raised, which bubbles out.
A Python generator is a function that produces a sequence of results. It works by maintaining its local state, so that the function can resume again exactly where it left off when called subsequent times. Thus, you can think of a generator as something like a powerful iterator.
The next() function returns the next item in an iterator. You can add a default return value, to return if the iterable has reached to its end.
Your first loop should still work -- StopIteration
will still be raised when a generator is exhausted.
The difference is that there was ambiguity when a StopIteration
was raised in a generator. Did it get raised (implicitly) because the generator ran out of things to yield -- Or did it get raised because a delegate generator ran out of things to yield (maybe due to a next
call) and the exception wasn't handled properly? PEP-0479 tries to address that ambiguity. Now if you get a StopIteration
, it means that the generator you are working with ran out items to yield. Said another way, it means that a delegate generator didn't get mis-handled when running out of items.
To support this change, your generator should return
instead of raising StopIteration
explicitly.
def gen():
yield from range(5)
return
Here's what happens if you try it with the StopIteration
and generator_stop
enabled (which will become the default when python3.7 comes around):
>>> from __future__ import generator_stop
>>> def gen():
... yield from range(5)
... raise StopIteration
...
>>> list(gen())
Traceback (most recent call last):
File "<stdin>", line 3, in gen
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With