Why does a Python Iterator need an iter method that simply returns self?

后端 未结 4 830
面向向阳花
面向向阳花 2021-01-06 05:35

I understand that the standard says that it does but I am trying to find the underlying reason for this.

If it simply always returns self what is the ne

相关标签:
4条回答
  • 2021-01-06 06:15

    for loops should work with iterables, so for i in something: automatically calls iter(something) to get an iterator and iterates over said iterator. Now if iterators weren't iterable too (i.e. did not define __iter__), you couldn't use for loops with iterators, i.e.:

    items = [1, 2, 3]
    # this would work
    for item in items: pass
    # this wouldn't
    it = iter(items)
    for item in it: pass
    

    Therefore, iterators should be iterables too. The alternative, "somehow detecting" iterators and not calling iter on them, is hacky and fragile (how would you decide that?).

    0 讨论(0)
  • 2021-01-06 06:16

    __iter__() is intended to return an iterator over the object. What is an iterator over an object that is already an iterator? self, of course.

    0 讨论(0)
  • 2021-01-06 06:25

    Imagine you want to write code that iterates over any kind of iterable. Normally you'd just write a for statement or comprehension, but let's instead explicitly do what for does under the covers, to make things more obvious:

    i = iter(iterable)
    while True:
        try:
            val = next(i)
        except StopIteration:
            break
        else:
            do_stuff(val)
    

    If you don't do that first line, your code won't work with lists, strings, tuples, or anything but iterator.

    But if you do that first line, well, iter(iterable) had better return an iterator, or your code won't work with iterators.


    You may wonder why iter couldn't just do the right thing without this? After all, it does have magic in it to create an iterator when given an object that has a __len__ and __getitem__ but no __iter__, so why couldn't it also have magic to just return its argument if it has a __next__ but no __iter__? That's a language-design issue, but generally, Python tries to have as little magic as possible. The magic to make not-quite-sequences iterable was necessary because such sequences existed (in widespread third-party code) before the iteration protocol was added to the language, and it would be too hard to remove for the small benefit of simplifying things.

    0 讨论(0)
  • 2021-01-06 06:31

    It's so for loops and other code that needs to work with iterables can unconditionally call iter on the thing they're iterating over, rather than treating iterators and other iterables separately. In particular, non-iterators might reasonably have a method called next, and we want to be able to distinguish them from iterators.

    0 讨论(0)
提交回复
热议问题