Possible File iteration bug

Thomas Rachel nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de
Fri Jul 15 16:46:30 EDT 2011

Am 15.07.2011 16:42 schrieb Billy Mays:

> A sentinel does provide a work around, but it also passes the problem
> onto the caller rather than the callee:

That is right.

BTW, there is another, maybe easier way to do this:

for line in iter(f.readline, ''):

This provides an iterator which yields return values from the given 
callable until '' is returned, in which case the iterator stops.

As caller, you need to have knowledge about the fact that you can always 

The functionality which you ask for COULD be accomplished in two ways:

Firstly, one could simply break the "contract" of an iterator (which 
would be a bad thing): just have your next() raise a StopIteration and 
then continue nevertheless.

Secondly, one could do a similiar thing and have the next() method raise 
a different exception. Then the caller has as well to know about, but I 
cannot find a passage in the docs which prohibit this.

I just have tested this:
def r(x): return x
def y(x): raise x

def l(f, x): return lambda: f(x)
class I(object):
     def __init__(self):
         self.l = [l(r, 1), l(r, 2), l(y, Exception), l(r, 3)]
     def __iter__(self):
         return self
     def next(self):
         if not self.l: raise StopIteration
         c = self.l.pop(0)
         return c()

i = I()
     for j in i: print j
except Exception, e: print "E:", e
print tuple(i)

and it works.

So I think it COULD be ok to do this:

class NotNow(Exception): pass

class F(object):
     def __init__(self, f):
         self.file = f
     def __iter__(self):
         return self
     def next(self):
         l = self.file.readline()
         if not l: raise NotNow
         return l

f = F(file("/var/log/messages"))
import time
while True:
         for i in f: print "", i,
     except NotNow, e:
         print "<pause>"



More information about the Python-list mailing list