I have been reading about Iterators in the python 2.7.x Documentation
The given sample program in the link defines a __iter__ method to make the class "iterable".
However, i cannot find any use of __iter__ method defined in the class, i.e. to say- Even if i don't define __iter__ , i can still iterate upon the object of the class.
Code 1 # From the documentation
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def next(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
Code 2 # Except for defining the iter method it's the same.
class ReverseMod:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
# Missing __iter__()
def next(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
Output:
rev = Reverse('spam')
revMod = ReverseMod('spam')
rev.next() #m
rev.next() #a
rev.next() #p
...
revMod.next() #m
revMod.next() #a
revMod.next() #p
...
Objects from class Reverse and ReverseMod behave the same way. Only thing is when i do a iter(revMod) it says
TypeError: iteration over non-sequence
Why do i even need to concern myself about doing iter(revMod)? Why do i need to care defining __iter__ at all. Seems like i can get the functionalities of doing a .next() without defining __iter__ at all.
for x in rev:andfor x in revMod:? What happened? What can you conclude about__iter__?Reverseis both an iterator and an iterable,ReverseModis only the former__iter__at all." - yes, but that's not the point. Nobody wants to callnextthemselves; they want to performforloops, or pass objects tolist, or do other things that won't work withReverseMod.nextbut not__iter__doesn't meet Python's definition of an iterator, even though it provides similar functionality. For example,isinstance(obj, collections.Iterator)will report that such an object is not an iterator.__iter__create a separate object. Making an iterator's__iter__implicitly reset the iterator breaks a few corner cases withnext-ing an iterator before you loop over it or continuing an iteration in a new loop, and it doesn't handle the common case of wanting to perform nested loops over a single object.