Search code examples
pythonfilereadline

How does readline() function really work in Python?


Here is my example:

My file:

abefgh
2345
6^7&8*
31
1
1

My code:

handle = open('TestFile','r')
for line in handle:
    print(handle.readline())
    

The output:

2345
31
1

Why does it only prints alternating lines?

Thank you, everyone. Now I understand that every time I run readline() command. The cursor moves to the end of the line. So the next time it will start to read from the next line. Please upvote so that I can post questions again. I can't post questions anymore. Thank you in advance!


Solution

  • In your code:

    handle = open('TestFile','r')
    for line in handle:
        print(handle.readline())
    

    The loop for line in handle already reads one line at time from handle. You then read the next line using handle.readline() and print that. That happens every iteration, so you only get every second line.

    The important thing to realise here is that .readline() doesn't remember where it is, handle does. So, when you open handle, it is at the start of the file. Then, when for gets the next line, it is at the start the second line. Then readline() reads up to and including the end of the next line, so it is at the start of the third line, etc.

    You want:

    handle = open('TestFile','r')
    for line in handle:
        print(line)
    

    Also, you want to close files and ideally you want to be sure they close without having to worry about closing them yourself, which is what context managers are for. Sounds complicated, but is really quite simple:

    with open('TestFile', 'r') as handle:
        for line in handle:
            print(line)
    

    This works because a file handle like handle is also an iterator and provides a __next__ method. This means that you can loop over it with for and it will yield its contents one element at a time. In the case of a text file, that means it will read one line and yield it, every time its __next__ method is called, either as next(handle) or when looped over with for.

    The with block ensures that handle is closed, as soon as the with block is exited.

    Finally, you'll probably end up wondering why your lines are printed with an empty line between them. That's because your file is a text file, where lines are separated by some sort of end of line character (or characters, on Windows).

    One way to get rid of those is to strip whitespace off of the end of the line:

    with open('TestFile', 'r') as handle:
        for line in handle:
            print(line.rstrip())
    

    Another way would be to read the whole file, split over line endings and the resulting lines won't have the line ending anymore:

    with open('TestFile', 'r') as handle:
        for line in handle.read().splitlines():
            print(line)