Here is my code:
from collections import deque
class linehistory:
def __init__(self, lines, histlen=3):
self.lines = lines
self.history = deque(maxlen=histlen)
def __iter__(self):
for lineno, line in enumerate(self.lines,1):
self.history.append((lineno, line))
yield line
def clear(self):
self.history.clear()
f = open('somefile.txt')
lines = linehistory(f)
next(lines)
Error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'linehistory' object is not an iterator
I have no idea why the linehistory
object is not an iterator since it has already included __iter__
method in the
class.
Wrong. See Iterator Types:
However you can iterate over
lines
, that's because your__iter__
method is a generator function, see Generator Types:Actually,
All these other answers are wrong (except for @glglgl who has an obtuse style of writing). Your generator function
__iter__()
would work as is if you called it with afor
loop like soBut because you used
next(lines)
you have to first useiter()
to get the iterator (I presume it just calls __iter__() on the object) like soas Mr.Beazley points out
The concept of iteration is well documented in the Python documentation.
In short, "iterable" is the object I want to iterate over, also called the container. This can be a list, a string, a tuple or anything else which consists of or can produce several items. It has
__iter__()
which returns an iterator.An "iterator" is the object which is used for one iteration. It can be seen as a kind of "cursor". It has
next()
(in Python 2) or__next__()
(in Python 3) which is called repeatedly until it raises aStopIteration
exception. As any iterator is iterable as well (being its own iterator), it also has__iter__()
which returns itself.You can get an iterator for any iterable with
iter(obj)
.In your example,
linehistory
(which should be writtenLineHistory
) is iterable as it has an.__iter__()
. The generator object created with this is an iterator (as every generator object).Iterator objects need an
__iter__
method but they also need to havenext
implemented:Python 2.7 Source
In Python 3.x these are the function names:
Python 3.x Source