尽管阅读了它,我仍然不太明白__iter__
的工作原理。什么是简单的解释?
我见过def__iter__(self): return self
。我不知道这是如何工作的或步骤如何工作。
答案 0 :(得分:23)
就像我可以说的那样:
__iter__
在类上定义一个方法,该方法将返回一个迭代器(一个连续产生对象包含的下一个项目的对象)。
__iter__()
返回的迭代器对象几乎可以是任何对象,只要它定义了next()
方法。
next
方法将由for ... in ...
之类的语句调用以生成下一个项目,next()
应该在没有其他项目时引发StopIteration
异常。< / p>
有什么好处是让你定义你的对象如何迭代,__iter__
提供了一个通用接口,每个其他python函数都知道如何使用它。
答案 1 :(得分:8)
迭代器需要定义两个方法:__iter__()
和__next__()
(python2中的next()
)。通常,对象本身定义__next__()
或next()
方法,因此它只返回迭代器。这将创建一个 iterable ,它本身也是一个迭代器。这些方法由for
和in
语句使用。
答案 2 :(得分:5)
def __iter__(self):
的规范是:它返回一个迭代器。因此,如果self
是迭代器,return self
显然是合适的。
“作为一个迭代器”意味着“有一个__next__(self)
方法”(在Python 3中;在Python 2中,所讨论的方法的名称很遗憾是next
,显然是一个名称设计故障一种特殊的方法)。
在Python 2.6及更高版本中,实现迭代器的最佳方法通常是使用collections
标准库module中的相应抽象基类 - 在Python 2.6中,代码可能是(记得在Python 3中调用方法__next__
:
import collections
class infinite23s(collections.Iterator):
def next(self): return 23
此类的实例将在迭代时返回无限多个23
的副本(如itertools.repeat(23)
),因此必须以其他方式终止循环。关键是子类化collections.Iterator
代表你添加正确的__iter__
方法 - 这里不是什么大问题,而是一个很好的一般原则(避免重复的样板代码,如迭代器的标准单行{{ 1}} - 在重复中,没有附加值和大量的减去值! - )。
答案 3 :(得分:2)
支持__iter__方法的类将返回一个迭代器对象实例:一个支持 next()方法的对象。该对象可在“for”和“in”语句中使用。
答案 4 :(得分:2)
在Python中,迭代器是支持迭代器协议的任何对象。该协议的一部分是该对象必须具有返回迭代器对象的__iter__()
方法。我想这给了你一些灵活性,以便一个对象可以将迭代器的职责传递给内部类,或者创建一些特殊的对象。在任何情况下,__iter__()
方法通常只有一行,而该行通常只是return self
协议的另一部分是next()
方法,这是实际工作的地方。此方法必须弄清楚或创建或获取下一个东西,并将其返回。它可能需要跟踪它的位置,以便下次调用时,它确实会返回下一个。
一旦你有一个返回序列中下一个东西的对象,你可以折叠一个如下所示的for循环:
myname = "Fredericus"
x = []
for i in [1,2,3,4,5,6,7,8,9,10]:
x.append(myname[i-1])
i = i + 1 # get the next i
print x
进入这个:
myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x
请注意,我们无法获得获取i的下一个值的代码,因为range(10)是一个跟随迭代器协议的对象,而list comprehension是一个使用迭代器协议的构造。
您也可以直接使用迭代器协议。例如,在编写脚本来处理CSV文件时,我经常写这个:
mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
# do something with the row.
我通过调用next()
直接使用迭代器跳过标题行,然后通过in
语句中的内置for
运算符间接使用它。