Arent these snippets equivalent?

Tim Chase python.list at
Thu Jan 24 00:29:47 CET 2013

On 01/23/13 16:47, Roy Smith wrote:
> while getchar() as c:
>     putchar(c)
> That would give people (including me) the use case they're after most of
> the time (call a function, assign the return value, and test it).  It's
> way less klunky than:
> while True:
>     c = getchar()
>     if c:
# I presume you mean "if not c:" here.
>        break
>     putchar()

I was a pretty strong advocate early in one of these long threads, 
and for the simple cases, it's some attractive syntactic sugar. 
However, I found that it quickly blossomed into a lot of really ugly 
edge cases (multiple tests, multiple results, checking for "is None" 
vs. false'ness or some other condition such as "< 0").  I found that 
it was pretty easy to create a generator-wrapper for this:

   def getter(fn):
     while True:
       val = fn()
       if not val: break
       yield val

   # DB example
   cursor = conn.cursor()
   for row in getter(lambda: cursor.fetchmany()):

   # your getchar example
   for c in getter(getchar):

This allowed me to have both the readability and customized tests 
(and the ability to return multiple values).  It could be expanded with

   def getter(fn, is_at_end=lambda v: not v):
     while True:
       val = fn()
       if is_at_end(val): break
       yield val

which would even allow you to do things like

   for line in getter(file("foo.txt"), lambda s: s.find("xxx") < 0):
     print "This line has 'xxx' in it:"
     print line

and those felt a lot more pythonic than any of the proposals I saw 
on the list.


More information about the Python-list mailing list