On 08/12/15 01:50, Robert wrote:
One example, see below please, is in the above mentioned link. I don't see
the purpose of the example.

OK, so there are two parts to this.

The first, is "how do I iterate over something". The answer to that is using "for" or using "iter()" followed by zero or more calls to "next()". In this case, by using the correct syntax/function calls your script can work under various versions of Python without change.

The second is "how do I make my own classes iterable". This is what the example you pasted is trying to show. In this case, you are implementing things which are "internal" to the way the version of Python you are using does things (which is why the code Robin posted wasn't quite right for you).

I have the following two same results. What do they tell me?

They tell you that the implementation does the same thing as the default implementation for a list. That perhaps doesn't help much - especially with the comment in the example telling you not to do it!

Instead, try the following (Python 2):

class MyList(list):
    def __iter__(self):
        return MyListIter(self)

class MyListIter(object):
    def __init__(self, lst):
        self.lst = lst
        self.i = -1

    def __iter__(self):
        return self

    def next(self):
        if self.i >= -len(self.lst):
            item = self.lst[self.i]
            self.i -= 1
            return item

        raise StopIteration

if __name__ == "__main__":
    a = MyList([1, 2, 3, 4])
    ia = iter(a)
    print 'type(a): %r, type(ia): %r' %(type(a), type(ia))
    for i in a:
        print i,
    print

    while True:
        print next(ia)

What we have here is the same class that subclasses 'list'. It's just a list. However, it has a custom iterator. In this implementation the iterator works BACKWARDS through the list - the final element is returned first, the penultimate element second, and so on. After the first element has been returned, the iterator raises StopIteration. This tells you not to call next() again, or if in a for loop, the loop is exited.

So, you can write your class's iterator to do anything that makes sense when someone says "for i in myclassinstance:".

If your class is a subclass of a class ("is-a") that already has a defined iterator (such as a list or a dict) and the behaviour of that is correct for you, then you need to do nothing (you inherit that class's __iter__() method).

If your class should iterate over an embedded object ("has-a") that already has a defined iterator, then your __iter__() method can just delegate to that object's iterator using something like:

def __iter__(self):
    return iter(self.embedded_thing)

Does that make more sense?
E.
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to