[Python-ideas] BUG in standard while statement

Petr Viktorin encukou at gmail.com
Wed Sep 9 21:12:18 CEST 2015


On Wed, Sep 9, 2015 at 7:20 PM, Stephan Sahm <Stephan.Sahm at gmx.de> wrote:
> It is so true!
> thanks for pointing that out. It makes sense to do it that way
> I probably never used while in different places than ``while 1: pass`` until
> now.
>
> I admit, I am looking for something alternative to a for structure like
> ``for _ in range(10)`` -- I don't like the ``_`` ;-)
> How can I use the iterator protocoll to make a nice repeat syntax?

If you don't like the ``_``, you can use ``for iteration_index in range(10):``.

You always need to store the iteration number somewhere (the original
post has it in ``self.n``). Chances are you'll want to access it
later, when you debug your code. Hiding it in a class is just making
it harder to get. It's also making the whole thing less maintainable,
because other people, who are used to seeing ``for i in range(...)``,
would now need to understand your custom class and new idiom. (And as
always with maintainability, "other people" includes you in a few
years.)

Instead, just use the current syntax. Eventually it will start looking
nice to you.


> On 9 September 2015 at 19:15, Joseph Jevnik <joejev at gmail.com> wrote:
>>
>> This appears as intended. The body of the while condition is executed each
>> time the condition is checked. In the first case, you are creating a single
>> instance of repeat, and then calling bool on the expression with each
>> iteration of the loop. With the second case, you are constructing a _new_
>> repeat instance each time. Think about the difference between:
>>
>> while should_stop():
>>     ...
>>
>> and:
>> a = should_stop()
>> while a:
>>     ...
>>
>> One would expect should_stop to be called each time in the first case;
>> but, in the second case it is only called once.
>>
>> With all that said, I think you want to use the __iter__ and __next__
>> protocols to implement this in a more supported way.
>>
>> On Wed, Sep 9, 2015 at 1:10 PM, Stephan Sahm <Stephan.Sahm at gmx.de> wrote:
>>>
>>> Dear all
>>>
>>> I found a BUG in the standard while statement, which appears both in
>>> python 2.7 and python 3.4 on my system.
>>>
>>> It usually won't appear because I only stumbled upon it after trying to
>>> implement a nice repeat structure. Look:
>>> ```
>>> class repeat(object):
>>>     def __init__(self, n):
>>>         self.n = n
>>>
>>>     def __bool__(self):
>>>         self.n -= 1
>>>         return self.n >= 0
>>>
>>>     __nonzero__=__bool__
>>>
>>> a = repeat(2)
>>> ```
>>> the meaning of the above is that bool(a) returns True 2-times, and after
>>> that always False.
>>>
>>> Now executing
>>> ```
>>> while a:
>>>     print('foo')
>>> ```
>>> will in fact print 'foo' two times. HOWEVER ;-) ....
>>> ```
>>> while repeat(2):
>>>     print('foo')
>>> ```
>>> will go on and go on, printing 'foo' until I kill it.
>>>
>>> Please comment, explain or recommend this further if you also think that
>>> both while statements should behave identically.
>>>
>>> hoping for responses,
>>> best,
>>> Stephan


More information about the Python-ideas mailing list