1

To read a file in Python, the file must be first opened, and then a read() function is needed. Why is that when we use a for loop to read lines of a file, no read() function is necessary?

filename = 'pi_digits.txt'
with open(filename,) as file_object:
    for line in file_object:
        print(line)

I'm used to the code below, showing the read requirement.

for line in file_object.read():
Prune
  • 76,765
  • 14
  • 60
  • 81
reza
  • 31
  • 1
  • 5
  • In general, you are probably doing something wrong if you call `read` without an argument. – chepner May 24 '17 at 21:08
  • 2
    Possible duplicate of [Python: When should I ever use file.read() or file.readlines()?](https://stackoverflow.com/questions/38105507/python-when-should-i-ever-use-file-read-or-file-readlines) – Arya McCarthy May 24 '17 at 21:11

3 Answers3

3

This is because the file_object class has an "iter" method built in that states how the file will interact with an iterative statement, like a for loop.

In other words, when you say for line in file_object the file object is referencing its __iter__ method, and returning a list where each index contains a line of the file.

Greg
  • 1,845
  • 2
  • 16
  • 26
0

The open command in your with statement handles the reading implicitly. It creates a generator that yields the file a record at a time (the read is hidden within the generator). For a text file, each line is one record.

Note that the read command in your second example reads the entire file into a string; this consumes more memory than the line-at-a-time example.

Prune
  • 76,765
  • 14
  • 60
  • 81
  • 1
    Also, `file_object.read()` returns a single string, whose iterator returns a single character at a time, where as a `file` iterator actually returns a line at a time. – chepner May 24 '17 at 21:07
  • This answer is incorrect, the `with` has nothing to do with it. Open the file any other way and the loop will behave the same. – alexis May 24 '17 at 21:11
  • 1
    I don't think it's wrong, just unclearly worded. `with open ... as` certainly opens the file (specifically, the call to `open` does; the `with` statement merely ensures it will be closed as well), although it is the resulting `file` object (or whatever `open` ends up returning in Python 3) which produces the iterator used by the `for` loop to actually read from the file. – chepner May 24 '17 at 21:21
  • I'd say it's misleading, at a minimum. It's hard to read it as _not_ saying, incorrectly, that the `with` plays a role. – alexis May 24 '17 at 21:36
  • I was keeping the explanation very intro-level, but you guys are right: it's technically misleading, and I need to edit it. – Prune May 24 '17 at 21:51
0

Python file objects define special behavior when you iterate over them, in this case with the for loop. Every time you hit the top of the loop it implicitly calls readline(). That's all there is to it.

Note that the code you are "used to" will actually iterate character by character, not line by line! That's because you will be iterating over a string (the result of the read()), and when Python iterates over strings, it goes character by character.

alexis
  • 48,685
  • 16
  • 101
  • 161