Feedback on Until recipe

Carsten Haese carsten at uniqsys.com
Thu Apr 26 01:05:06 EDT 2007


On Wed, 2007-04-25 at 19:11 -0700, Paul McGuire wrote:
> I moved the state into the Until instance vs. the Until class, so that
> it now supports nesting.  But the calling syntax is even uglier - but
> necessary to avoid creating a new Until instance each time around.
> That is "while Until(blah):" evaluates and constructs a new Until
> instance each time around the loop, so that is why the state had to be
> kept in a class-level variable in your original design (which is why
> nesting doesn't work).
> 
> class Until:
>     def __init__(self, mybool):
>         self.lastTest = True
>         self.mybool = mybool
> 
>     def __nonzero__(self):
>         ret,self.lastTest = self.lastTest,self.mybool()
>         return ret
> 
> i = 0
> u1 = Until(lambda : i < 0 )
> while u1:
>     print "hello"
>     i += 1
>     j = 0
>     u2 = Until(lambda : j < 0 )
>     while u2:
>         print "byebye"
>         j += 1

Using iterators is a way around the problem of making a new instance
every time around the loop, but the calling syntax is not much nicer
since it is shoehorned into a for-loop. Note that I've renamed the beast
in order to reflect what it actually does: The loop body is repeated as
long as the given condition is true.

class RepeatAsLongAs(object):
    def __init__(self, cond):
        self.cond = cond
        self.previousTest = True
    def __iter__(self):
        return self
    def next(self):
        ret, self.previousTest = self.previousTest, self.cond()
        if not ret: raise StopIteration
        return ret

i = 0
for _ in RepeatAsLongAs(lambda: i<0):
    print "hello"
    i += 1
    j = 0
    for _ in RepeatAsLongAs(lambda: j<0):
        print "byebye"
        j += 1

Having said that, I don't see myself ever using such a beast. The
equivalent code

while True:
  # do something
  if until_condition: break

is much more concise, much easier to understand, and it shows explicitly
that the condition is checked after the loop body is executed.

-Carsten





More information about the Python-list mailing list