11

誰かが PEP479 が何であるかを理解するのを手伝ってくれますか? 私はドキュメントを読んでいましたが、頭に浮かびませんでした。

要約は次のように述べています。

この PEP は、ジェネレーターへの変更を提案します。ジェネレーター内で StopIteration が発生すると、RuntimeError に置き換えられます。(より正確には、これは、例外がジェネレーターのスタック フレームから出ようとしているときに発生します。)

たとえば、そのようなループはまだ機能しますか?

it = iter([1,2,3])
try:
    i = next(it)
    while True:
        i = next(it)
except StopIteration:
    pass

または、次のようなジェネレーター定義がある場合は、次のようになります。

def gen():
    yield from range(5)
    raise StopIteration

は?StopIterationに置き換えられます。RuntimeError

誰かがこれに光を当てることができれば、本当に感謝しています。

4

1 に答える 1

15

最初のループは引き続き機能するはずStopIterationです。ジェネレーターが使い果たされても発生します。

違いは、ジェネレーターで a が発生したときにあいまいさがあったことです。StopIterationジェネレーターが生成するものを使い果たしたために (暗黙的に) 発生しましたか? それとも、デリゲート ジェネレーターが生成するものを使い果たし (おそらくnext呼び出しが原因で)、例外が適切に処理されなかったために発生しましたか? PEP-0479 は、そのあいまいさに対処しようとします。StopIterationが表示された場合は、使用しているジェネレーターが生成するアイテムを使い果たしたことを意味します。別の言い方をすれば、アイテムが不足したときにデリゲート ジェネレーターが誤って処理されなかったことを意味します。

この変更をサポートするために、ジェネレーターは明示的returnにレイズする代わりにすべきです。StopIteration

def gen():
    yield from range(5)
    return

StopIterationを有効にして試してみると、次のようgenerator_stopになります (これは、python3.7 が登場したときにデフォルトになります)。

>>> 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
于 2016-06-08T15:56:20.490 に答える