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