ジェネレーターと一緒に遊んでいるうちに、興味深いものが見つかりました。私がyield
キーワードで関数を定義し、そこからジェネレータを受け取ったとき、関数を与えられたシーケンスで変数を削除しました。そして* POOF!* - ジェネレータは空になります。ここに私のステップがあります:ジェネレーターからの奇妙な振る舞い
>>> def foo(list_):
... for i in list_:
... yield i*2
...
>>> val = [1, 2, 3, 4]
>>> gen = foo(val)
>>> print(tuple(gen))
(2, 4, 6, 8)
>>> del val
>>> print(tuple(gen))
()
>>>
不変ではありませんか?あるいは、実際に変数としての値をすべてのオブジェクトに渡すオブジェクトとして機能している場合は、出力を与え、リンクされたシーケンスがないために例外をスローしなかったのはなぜですか?実際には、この例は空のシーケンスを繰り返し処理するかのように説明することができ、その結果、ブロックfor _ in []:
は起動しません。
>>> def foo(list_):
... for i in list_:
... yield i*2
...
>>> val = [1, 2, 3, 4]
>>> gen = foo(val)
>>> print(tuple(gen))
(2, 4, 6, 8)
>>> del foo
>>> print(tuple(gen))
()
>>>
は発電機がここdict.get()
機能に似て行動しています:このが例外をスローしませんしかし、なぜ、私が説明カント?私はこれを理解していない。
あなたは 'デルval'をしたという事実を:
gen
自体はまだそれが完了するまでに必要なものを参照するため、そうgen = foo(val); del foo, val
が、それはまだ、既存のいずれかfoo
またはval
参照せずに値を生成することができ、gen
オブジェクトを中断されませんあなたが観察したジェネレータの動作とは何の関係もありません。あなたが 'del val'をしなかったなら、あなたは同じ結果を見たでしょう。 – user2357112