Is there an easy way to tell which line number a file pointer is on?

Mike T picture Mike T · Jun 16, 2011 · Viewed 33.5k times · Source

In Python 2.5, I am reading a structured text data file (~30 MB in size) using a file pointer:

fp = open('myfile.txt', 'r')
line = fp.readline()
# ... many other fp.readline() processing steps, which
# are used in different contexts to read the structures

But then, while parsing the file, I hit something interesting that I want to report the line number of, so I can investigate the file in a text editor. I can use fp.tell() to tell me where the byte offset is (e.g. 16548974L), but there is no "fp.tell_line_number()" to help me translate this to a line number.

Is there either a Python built-in or extension to easily track and "tell" what line number a text file pointer is on?

Note: I'm not asking to use a line_number += 1 style counter, as I call fp.readline() in different contexts and that approach would require more debugging than it is worth to insert the counter in the right corners of the code.

Answer

Greg Hewgill picture Greg Hewgill · Jun 16, 2011

A typical solution to this problem is to define a new class that wraps an existing instance of a file, which automatically counts the numbers. Something like this (just off the top of my head, I haven't tested this):

class FileLineWrapper(object):
    def __init__(self, f):
        self.f = f
        self.line = 0
    def close(self):
        return self.f.close()
    def readline(self):
        self.line += 1
        return self.f.readline()
    # to allow using in 'with' statements 
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

Use it like this:

f = FileLineWrapper(open("myfile.txt", "r"))
f.readline()
print(f.line)

It looks like the standard module fileinput does much the same thing (and some other things as well); you could use that instead if you like.