Search code examples
pythontext-filesline-numbers

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


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.


Solution

  • 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.