0

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.

8
  • 1
    Have you tried for x in rev: and for x in revMod:? What happened? What can you conclude about __iter__? Commented May 4, 2016 at 17:18
  • Reverse is both an iterator and an iterable, ReverseMod is only the former Commented May 4, 2016 at 17:18
  • 2
    "Seems like i can get the functionalities of doing a .next() without defining __iter__ at all." - yes, but that's not the point. Nobody wants to call next themselves; they want to perform for loops, or pass objects to list, or do other things that won't work with ReverseMod. Commented May 4, 2016 at 17:19
  • 1
    @jonrsharpe: Strictly speaking, an object that provides next but 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. Commented May 4, 2016 at 17:23
  • 1
    @PM2Ring: Bad move. If you want something to support iterating over it repeatedly like that, it's much better to make __iter__ create a separate object. Making an iterator's __iter__ implicitly reset the iterator breaks a few corner cases with next-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. Commented May 4, 2016 at 18:38

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.