问题描述
我已经阅读了我的材料,其中告诉 Python 迭代器必须同时具有 __iter__ 和 __next__ 方法,但迭代器只需要 __iter__.
I have read my materials, which tell that a Python iterator must have both __iter__ and __next__ methods, but an iterable just needs __iter__.
我检查了一个列表,发现它没有 __next__ 方法.当在其上使用 iter() 时,它将成为一个迭代器.这是否意味着 iter() 会在列表中添加一个 __next__ 方法以将其转换为迭代器?
I check a list and find it has no __next__ method. When using iter() on it, it will become an iterator. Does this mean that iter() will add a __next__ method to a list to convert it to an iterator?
如果是,这是怎么发生的?
If yes, how does this happen?
推荐答案
没有.iter 返回一个迭代器,它不会将列表转换为迭代器.它根本不修改列表,当然,列表没有得到 __next__ 方法.
No. iter returns an iterator, it does not convert the list into an iterator. It doesn't modify the list at all, and certainly, the list does not get a __next__ method.
>>> x = [1,2] >>> it = iter(x) >>> it <list_iterator object at 0x101c021d0> >>> x.__next__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'list' object has no attribute '__next__' >>>
列表是iterables,而不是iterators.它们实现了一个 __iter__ 方法,因此它们是可迭代的:
Lists are iterables, not iterators. They implement a __iter__ method, thus they are iterable:
>>> x.__iter__ <method-wrapper '__iter__' of list object at 0x101bcf248>
但不是 __next__,因此它们不是迭代器:
But not __next__, thus they are not iterators:
>>> next(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'list' object is not an iterator
根据定义,迭代器本身是可迭代的,因为它们也实现了 __iter__.考虑:
Iterators themselves are iterable, by definition, since they implement __iter__ as well. Consider:
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> it = iter(x) >>> it <list_iterator object at 0x101c02358> >>> it.__iter__ <method-wrapper '__iter__' of list_iterator object at 0x101c02358>
大多数迭代器应该在你对它们使用iter时简单地返回它们自己:
Most iterators should simply return themselves when you use iter on them:
>>> it2 = iter(it) >>> it, it2 (<list_iterator object at 0x101c02358>, <list_iterator object at 0x101c02358>) >>> it is it2 True >>>
确实,这是迭代器协议的要求:
"迭代器必须有一个返回的 __iter__() 方法迭代器对象本身,因此每个迭代器也是可迭代的,并且可能是在接受其他迭代的大多数地方使用."
"Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted."
再次注意,它们是同一个迭代器:
>>> next(it) 1 >>> next(it2) 2 >>> next(it) 3 >>> next(it) 4 >>> next(it2) 5 >>> list(it) [6, 7, 8, 9] >>> next(it2) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
所以一个iterator实现了__iter__和__next__,一个iterable仅仅意味着它实现了__iter__代码>.返回 __iter__ 是一个迭代器,所以它必须实现 __next__.
So an iterator implements __iter__ and __next__, an iterable just means that it implements __iter__. What is returned by __iter__ is an iterator, so that must implement __next__.