__next__ and StopIteration

Chris Kaynor ckaynor at zindagigames.com
Tue Feb 10 12:27:32 EST 2015


On Tue, Feb 10, 2015 at 12:30 AM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
>
> On Mon, Feb 9, 2015 at 5:59 PM, Chris Kaynor <ckaynor at zindagigames.com> wrote:
> > On Mon, Feb 9, 2015 at 4:42 PM, Steven D'Aprano
> > <steve+comp.lang.python at pearwood.info> wrote:
> >> so that's an excellent sign that doing so is best practice, but it should
> >> not be seen as *required*. After all, perhaps you have good reason for
> >> wanting your iterable class to only be iterated over once.
> >
> > In fact, there is one in the stdlib, the "file" object, which has a
> > __iter__ which returns self. The code below shows this,
>
> Fair point. I suppose that's because the file paradigm itself has a
> concept of current position that can't easily be abstracted away.

That is basically my thought as well. It would be possible to seek
around the file while iterating (seek to the current iteration
position, read, then seek back to the previous location), however that
would slow down iteration for little practical gain. It would also
require locking and possibly introduce odd corner cases.

>
> > The "file" object is also an example of this. It is technically a
> > broken iterator according to the docs:
> >
> > Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600
> > 32 bit (Intel)] on win32
> > Type "help", "copyright", "credits" or "license" for more information.
> >>>> f = open("d:/test.txt")
> >>>> iter(f) is f
> > True
> >>>> for l in f:
> > ...     print(l)
> > ...
> > line 1
> >
> > line 2
> >
> > line 3
> >
> >>>> for l in f:
> > ...     print(l)
> > ...
> >>>> f.seek(0)
> > 0
> >>>> for l in f:
> > ...     print(l)
> > ...
> > line 1
> >
> > line 2
> >
> > line 3
> >
> >>>> next(f)
> > Traceback (most recent call last):
> >   File "<stdin>", line 1, in <module>
> > StopIteration
> >>>> f.seek(0)
> > 0
> >>>> next(f) # This should throw StopIteration as it has previously thrown StopIteration.
> > 'line 1\n'
>
> IIRC the docs also warn that mixing file iteration with other file
> methods results in undefined or broken behavior. Maybe that's only for
> Python 2 files, however.


>From the 2.7.9 docs (https://docs.python.org/2/library/stdtypes.html#file.next):
> As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.

So it explicitly states that seek, the method I used, should work
fine. I could not find any similar text in the 3.4 docs.

Chris



More information about the Python-list mailing list