Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #75346 > unrolled thread

Re: What happens when you 'break' a generator?

Started by"Frank Millman" <frank@chagford.com>
First post2014-07-29 09:51 +0200
Last post2014-07-29 09:51 +0200
Articles 1 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: What happens when you 'break' a generator? "Frank Millman" <frank@chagford.com> - 2014-07-29 09:51 +0200

#75346 — Re: What happens when you 'break' a generator?

From"Frank Millman" <frank@chagford.com>
Date2014-07-29 09:51 +0200
SubjectRe: What happens when you 'break' a generator?
Message-ID<mailman.12412.1406620295.18130.python-list@python.org>
"Peter Otten" <__peter__@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


[toc] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web