2

I am trying to learn python and encounter the following snippet of code

f = open('test.txt')
for line in f:
    print line

It prints the content in my file, line by line.

I understand for loop's basic concept: for x in list when list is a list it will go through all the element in the list. My question is, f is a file object, not a list, how come the for loop magically understands there are lines in the file and process it one by one?

If someone can explain what happen exactly with the for loop in the above code that will be very helpful. Thanks!

SunnyIsaLearner
  • 750
  • 2
  • 13
  • 26
  • Required reading for anyone trying to understand this: https://docs.python.org/2/reference/datamodel.html. It explains how classes can implement methods that make them behave like builtins. – SethMMorton Mar 08 '17 at 19:15
  • 1
    Specifically, list iterators and file handles both support the [iterator protocol](https://docs.python.org/2/library/stdtypes.html#iterator-types) – wim Mar 08 '17 at 19:17
  • [Here](https://gist.github.com/juanarrivillaga/e6a68d70cbae3d2ca72f3d81f869d4f6) is a gist that explains what a for-loop does underneath the hood. Please note, this actually isn't implemented in Python, but in whatever language the interpreter is written in. So, C in CPython, or Java in Jython. So, essentially, file-handles implement an `__iter__` (which just returns self) and a `__next__` method which returns the next line, making it super convenient to iterate line-by-line! Isn't Python great! – juanpa.arrivillaga Mar 08 '17 at 19:31
  • I actually think [this](http://stackoverflow.com/questions/29403401/python-for-loop-and-iterator-behavior) is the more appropriate duplicate. In any event, it is worth reading the accepted answer. – juanpa.arrivillaga Mar 08 '17 at 19:35
  • @wim you've got a gold-badge, can you maybe change the link the duplicate is pointing to? I leave it up to goldbadgers to decide ;). They would both be appropriate, but IMO, this particular question (especially the title) is more generic than specifically file-handles. – juanpa.arrivillaga Mar 08 '17 at 19:37
  • I checked both, and I think the existing link is better. The more generic question remains in the sidebar under "Linked", which is fine. – wim Mar 08 '17 at 19:59

2 Answers2

2

Any object can provide an interface for iteration by implementing the method __iter__, which must return an iterator. An iterator is any object that provides a next method (__next__ in Python 3) to return the next element in the iteration and an __iter__ method that returns the iterator itself (to support using iterators in for loops directly). In this case, the file object defines __iter__ to return the file object itself (so file objects are their own iterators), and it defines next to return the next line in the file.

user2357112
  • 260,549
  • 28
  • 431
  • 505
BallpointBen
  • 9,406
  • 1
  • 32
  • 62
  • Iterators and iterables are different. And it's `next` in python-2.7, not `__next__`. – wim Mar 08 '17 at 19:18
  • Would be more helpful to explain why they are different. An iterable is an object which returns an iterable using an __iter__ method. – Denziloe Mar 08 '17 at 19:21
  • 1
    iterables implement an `__iter__` method, but do *not* have a `__next__` method. Iterators have `__iter__` (which might just return self) *and* a `__next__`. So, for example, `range(10)` in *iterable*. Calling `iter` on it returns an *iterator*. `r = range(10); it =iter(r)`. Note, if I do `next(r)` the interpreter complains`TypeError: 'range' object is not an iterator`. But if I do `next(it)`, I get the next value! – juanpa.arrivillaga Mar 08 '17 at 19:21
  • I should note, my comment above was speaking in terms of Python 3, where `next` methods have been made into a "dunder" `__next__` method. – juanpa.arrivillaga Mar 08 '17 at 19:24
1

File objects support iterator protocol.

When a file is used as an iterator, typically in a for loop, the next() method is called repeatedly.

Refer file.next()

franklinsijo
  • 17,784
  • 4
  • 45
  • 63