Iterator Protocol. Is it dark magic?

So, I wrote iterators for a while, and I thought I understood them. But today I am struggling with some problems, and the more I play with it, the more embarrassed I become.

I thought that for an iterator you need to implement __iter__and next(or __next__). And when you first tried to iterate over the iterator, the method will be called __iter__, and then it nextwill be called until it is raised StopIteration.

When I run this code though

class Iter(object):

    def __iter__(self):
        return iter([2, 4, 6])

    def next(self):
        for y in [1, 2, 3]:
            return y

iterable = Iter()
for x in iterable:
    print(x)

Output signal 2 4 6. Therefore it __iter__is called, but not next. This is similar to the documentation I found here . But then it causes me a whole bunch of questions.

, , next? , ? , , next , for x in Iter(), ?

+4
2

, . :

>>> type([])
list
>>> type(iter([]))
list_iterator

iter .

, , [2, 4, 6], 1, 2, 3.

def __iter__(self):
    return iter([2, 4, 6])  # <-- you're returning the list iterator, not your own

, Python 2, , , - .

class Iter(object):

    def __iter__(self):
        self.val = 0
        return self

    def next(self):
        self.val += 1
        if self.val > 3:
            raise StopIteration
        return self.val
+6

, , iterator __iter__ . , : for __iter__ , iter([2,4,6]), self.

( , , next , : 1 , , StopIteration. , __iter__, , [1, 2, 3]. .)

+2

Source: https://habr.com/ru/post/1671212/


All Articles