"Peter Otten" <__pete...@web.de> wrote in message news:lr7ilg$de4$1...@ger.gmane.org... > Frank Millman wrote: > >> Hi all >> >> Python 3.4.1 >> >> Here is a simple generator - >> >> def test(): >> print('start') >> for i in range(5): >> yield i >> print('done') >> >> x = test() >> for j in x: >> print(j) >> >> As expected, the output is - >> >> start >> 0 >> 1 >> 2 >> 3 >> 4 >> done >> >> Here I break the loop - >> >> x = test() >> for j in x: >> print(j) >> if j == 2: >> break >> >> Now the output is - >> >> start >> 0 >> 1 >> 2 >> >> 'done' does not appear, so the generator does not actually terminate. >> What >> happens to it? >> >> My guess is that normal scoping rules apply. Using my example, the >> generator is referenced by 'x', so when 'x' goes out of scope, the >> generator is garbage collected, even though it never completed. >> >> Is this correct? > > Yes. In newer Pythons try...finally works, so you can see for yourself: > >>>> def f(): > ... try: > ... for c in "abc": yield c > ... finally: > ... print("done") > ... >>>> g = f() >>>> for c in g: > ... print(c) > ... if c == "b": break > ... > a > b >>>> del g > done > > Also: > >>>> g = f() >>>> next(g) > 'a' >>>> g.throw(GeneratorExit) > done > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 3, in f > GeneratorExit > >
Thanks for the clarification, Peter. The subconscious does funny things. When I scanned your reply quickly, I could have sworn it said something about 'forcing a break'. When I read it more slowly, I could not find that. Then I realised it actually says 'for c in g' ... Frank -- https://mail.python.org/mailman/listinfo/python-list