exception raised by nested iterator being ignored by for loop

J

james t kirk

I'm writing a wrapper class to handle the line merging and filtering
for a log file analysis app

The problem I'm running into is that the StopIteration exception
raised when the wrapped file goes past EOF isn't causing the second
for loop to stop. Wrapping the second for loop in a try/except clause
shows that the exception is being raised though.

Could someone more familiar with the underlying implementation please
give me a hint as to why this is happening?


import gzip
class wrapper :

def __init__ (self, filename) :
if filename[-3:] == ".gz" :
self.fh = gzip.GzipFile(filename, "r")
else :
self.fh = open(filename, "r")

def __iter__ (self) :
return self

def next (self) :
for line in self.fh : # StopIteration raised here when
file exhausted
if line[:1] == "t" : # filter out lines starting with
't'
continue
return line.rstrip()

if __name__ == "__main__" :
# using the file handle
fh = open("test.txt")
for line in fh :
print line.rstrip()
fh.close()

# using the wrapper class
fh = wrapper("test.txt")
for line in fh : # StopIteration ignored here
print line
 
R

Raymond Hettinger

james said:
I'm writing a wrapper class to handle the line merging and filtering
for a log file analysis app

The problem I'm running into is that the StopIteration exception
raised when the wrapped file goes past EOF isn't causing the second
for loop to stop.

Admiral Kirk,

The innermost for-loop is catching its own StopIteration. You need to
explicitly raise StopIteration in your next() method when there are no
more lines in the file (hint, add an else-clause to the for-loop).

Alternatively, you could simplify your life by writing the whole
wrapper as a generator:


import gzip

def wrapper(filename) :
if filename[-3:] == ".gz" :
fh = gzip.GzipFile(filename, "r")
else :
fh = open(filename, "r")
for line in fh:
if line[:1] != "t": # filter out lines starting with 't'
yield line.rstrip()
fh.close()


Raymond Hettinger
Starfleet Command
 
B

Bengt Richter

I'm writing a wrapper class to handle the line merging and filtering
for a log file analysis app

The problem I'm running into is that the StopIteration exception
raised when the wrapped file goes past EOF isn't causing the second
for loop to stop. Wrapping the second for loop in a try/except clause
shows that the exception is being raised though.

Could someone more familiar with the underlying implementation please
give me a hint as to why this is happening?
import gzip
class wrapper :

def __init__ (self, filename) :
if filename[-3:] == ".gz" :
self.fh = gzip.GzipFile(filename, "r")
else :
self.fh = open(filename, "r")

def __iter__ (self) :
return self

def next (self) :
for line in self.fh : # StopIteration raised here when
file exhausted
Yes, but that just ends the for loop and that uses up the exception, so either
change the above "for ..." to two lines: (untested ;-/ )
while True:
line = self.fh.next() # should raise StopIteration without
# being caught by for
if line[:1] == "t" : # filter out lines starting with
't'
continue
return line.rstrip()
or otherwise the end of the for will catch the StopIteration and just drop out here.
Imagine you were just printing the line in the loop body instead of checking and
returning lines. With just a print, you wouldn't expect a StopIteration to escape the for loop, right?
If you want to leave the for unchanged, you could just tell the world that the wrapper iteration
is done, by using the following line here:
raise StopIteration # end of wrapper iteration
if __name__ == "__main__" :
# using the file handle
fh = open("test.txt")
for line in fh :
print line.rstrip()
fh.close()

# using the wrapper class
fh = wrapper("test.txt")
for line in fh : # StopIteration ignored here
print line

HTH (and that the untested code works ;-)

Regards,
Bengt Richter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top