Python PEP479 更改生成器内部的 StopIteration 处理 [英] Python PEP479 Change StopIteration handling inside generators

查看:55
本文介绍了Python PEP479 更改生成器内部的 StopIteration 处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能帮我理解 PEP479 是关于什么的吗?我正在阅读文档并且无法理解它.

摘要说:

<块引用>

此 PEP 提议对生成器进行更改:当在生成器内部引发 StopIteration 时,将其替换为 RuntimeError.(更准确地说,这发生在异常即将从生成器的堆栈帧中冒出时.)

例如,像这样的循环是否仍然有效?

it = iter([1,2,3])尝试:我 = 下一个(它)为真:我 = 下一个(它)除了停止迭代:经过

或者这是否意味着如果我有这样的生成器定义:

def gen():从范围(5)的产量引发停止迭代

StopIteration 将被替换为 RuntimeError?

如果有人能对此有所了解,我将不胜感激.

解决方案

你的第一个循环应该仍然有效——StopIteration 在生成器耗尽时仍然会被引发.

不同之处在于,在生成器中引发 StopIteration 时, 会产生歧义.它被引发(隐式)是因为生成器用完了要让出的东西 - 还是因为委托生成器用完要让出的东西(可能是由于 next 调用)和异常没有正确处理?PEP-0479 试图解决这种歧义.现在,如果您获得 StopIteration,则意味着您正在使用的生成器耗尽了要生成的项目.换句话说,这意味着委托生成器没有在项目用完时处理不当.

为了支持这个改变,你的生成器应该return而不是显式提高StopIteration.

def gen():从范围(5)的产量返回

<小时>

如果你在启用 StopIterationgenerator_stop 的情况下尝试它会发生什么(当 python3.7 出现时这将成为默认值):

<预><代码>>>>从 __future__ 导入 generator_stop>>>定义生成():... 从 range(5) 产生...引发停止迭代...>>>列表(gen())回溯(最近一次调用最后一次):文件<stdin>",第 3 行,在 gen停止迭代上述异常是以下异常的直接原因:回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中运行时错误:生成器引发了 StopIteration

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.

解决方案

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

这篇关于Python PEP479 更改生成器内部的 StopIteration 处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆