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 -- http://mail.python.org/mailman/listinfo/python-list