このコードでは、なぜfor
を使用してもStopIteration
にならないのか、またはfor
ループがすべての例外をトラップしてから静かに終了するのですか?その場合、なぜ余分なreturn
があるのですか??またはraise StopIteration
のせいで: return None
?
#!/usr/bin/python3.1
def countdown(n):
print("counting down")
while n >= 9:
yield n
n -= 1
return
for x in countdown(10):
print(x)
c = countdown(10)
next(c)
next(c)
next(c)
StopIteration
が以下によってトリガーされていると仮定します:return None
。 GeneratorExit
はいつ生成されますか?
def countdown(n):
print("Counting down from %d" % n)
try:
while n > 0:
yield n
n = n - 1
except GeneratorExit:
print("Only made it to %d" % n)
私が手動で行う場合:
c = countdown(10)
c.close() #generates GeneratorExit??
どの場合、トレースバックが表示されないのですか?
for
ループは、StopIteration
を明示的にリッスンします。
for
ステートメントの目的は、イテレーターによって提供されるシーケンスをループすることであり、例外はイテレーターが終了したことを示すために使用されます。 for
は、反復されるオブジェクトによって発生した他の例外をキャッチしません。
これは、StopIteration
が、生成されるものがこれ以上ないことを反復している人に知らせるための通常の予想される信号だからです。
ジェネレーター関数は特別な種類のイテレーターです。関数が完了すると、実際にStopIteration
が発生します(つまり、戻るときに、そう、はい、_return None
_はStopIteration
を発生させます)。反復子の要件です。それらはmust終了したらStopIteration
を上げます;実際、StopIteration
が発生すると、それらから別の要素を取得しようとする(next()
を介して、または.next()
(py 2)または.__next__()
(py 3)イテレータのメソッド)mustは常にStopIteration
を再度発生させます。
GeneratorExit
は、other方向で通信する例外です。明示的にclosingyield
式を持つジェネレーターであり、方法Pythonはそのクロージャーを通信しますジェネレーターは、その関数内でGeneratorExit
を上げることにより、countdown
内で明示的に例外をキャッチします。
GeneratorExit
は呼び出し元に伝播されません。 generator.close()
documentation を参照してください。