python __iter__ 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1610371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:42:09  来源:igfitidea点击:

How does __iter__ work?

pythoniterator

提问by sss

Despite reading up on it, I still dont quite understand how __iter__works. What would be a simple explaination?

尽管阅读了它,但我仍然不太明白它是如何__iter__工作的。什么是简单的解释?

I've seen def__iter__(self): return self. I don't see how this works or the steps on how this works.

我见过def__iter__(self): return self。我不明白这是如何工作的,也没有看到如何工作的步骤。

采纳答案by hasen

An iterator needs to define two methods: __iter__()and __next__()(next()in python2). Usually, the object itself defines the __next__()or next()method, so it just returns itself as the iterator. This creates an iterablethat is also itself an iterator. These methods are used by forand instatements.

迭代器需要定义两个方法:__iter__()__next__()next()在python2中)。通常,对象本身定义了__next__()ornext()方法,因此它只是将自身作为迭代器返回。这将创建一个迭代器,它本身也是一个迭代器。这些方法由forin语句使用。

回答by Gabriel Hurley

As simply as I can put it:

就像我能说的那样简单:

__iter__defines a method on a class which will return an iterator (an object that successively yields the next item contained by your object).

__iter__在一个类上定义一个方法,该方法将返回一个迭代器(一个对象,它连续产生您的对象包含的下一个项目)。

The iterator object that __iter__()returns can be pretty much any object, as long as it defines a next()method.

__iter__()返回的迭代器对象几乎可以是任何对象,只要它定义了一个next()方法。

The nextmethod will be called by statements like for ... in ...to yield the next item, and next()should raise the StopIterationexception when there are no more items.

next方法将被语句调用for ... in ...以产生下一个项目,并且在没有更多项目时next()应该引发StopIteration异常。

What's great about this is it lets youdefine how your object is iterated, and __iter__provides a common interface that every other python function knows how to work with.

这样做的好处在于,它允许定义对象的迭代方式,并__iter__提供一个通用接口,每个其他 Python 函数都知道如何使用该接口。

回答by Alex Martelli

The specs for def __iter__(self):are: it returns an iterator. So, if selfis an iterator, return selfis clearly appropriate.

规范def __iter__(self):是:它返回一个迭代器。所以,ifself是一个迭代器,return self显然是合适的。

"Being an iterator" means "having a __next__(self)method" (in Python 3; in Python 2, the name of the method in question is unfortunately plain nextinstead, clearly a name design glitch for a special method).

“作为迭代器”意味着“拥有一个__next__(self)方法”(在 Python 3 中;在 Python 2 中,不幸的是,所讨论的方法的名称很简单next,显然是特殊方法的名称设计故障)。

In Python 2.6 and higher, the best way to implement an iterator is generally to use the appropriate abstract base class from the collectionsstandard library module-- in Python 2.6, the code might be (remember to call the method __next__instead in Python 3):

在 Python 2.6 及更高版本中,实现迭代器的最佳方法通常是使用来自collections标准库模块的适当抽象基类——在 Python 2.6 中,代码可能是(记住__next__在 Python 3 中调用该方法):

import collections

class infinite23s(collections.Iterator):
  def next(self): return 23

an instance of this class will return infinitely many copies of 23when iterated on (like itertools.repeat(23)) so the loop must be terminated otherwise. The point is that subclassing collections.Iteratoradds the right __iter__method on your behalf -- not a big deal here, but a good general principle (avoid repetitive, boilerplate code like iterators' standard one-line __iter__-- in repetition, there's no added value and a lot of subtracted value!-).

此类的实例将23在迭代时返回无限多个副本(如itertools.repeat(23)),因此必须否则终止循环。关键是子类化代表你collections.Iterator添加了正确的__iter__方法——这里没什么大不了的,但这是一个很好的一般原则(避免重复的样板代码,比如迭代器的标准单行__iter__——重复,没有附加价值,很多减去值!-)。

回答by jldupont

A class supporting the __iter__ method will return an iterator object instance: an object supporting the next()method. This object will be usuable in the statements "for" and "in".

支持 __iter__ 方法的类将返回一个迭代器对象实例:一个支持next()方法的对象。这个对象将在语句“for”和“in”中可用。

回答by Michael Dillon

In Python, an iterator is any object that supports the iterator protocol. Part of that protocol is that the object must have an __iter__()method that returns the iterator object. I suppose this gives you some flexibility so that an object can pass on the iterator responsibilities to an internal class, or create some special object. In any case, the __iter__()method usually has only one line and that line is often simply return self

在 Python 中,迭代器是任何支持迭代器协议的对象。该协议的一部分是对象必须具有__iter__()返回迭代器对象的方法。我想这为您提供了一些灵活性,以便对象可以将迭代器职责传递给内部类,或者创建一些特殊对象。在任何情况下,该__iter__()方法通常只有一行,而该行通常很简单return self

The other part of the protocol is the next()method, and this is where the real work is done. This method has to figure out or create or get the next thing, and return it. It may need to keep track of where it is so that the next time it is called, it really does return the next thing.

协议的另一部分是next()方法,这是真正完成工作的地方。此方法必须找出或创建或获取下一个事物,然后返回它。它可能需要跟踪它的位置,以便下次调用它时,它确实返回下一件事。

Once you have an object that returns the next thing in a sequence, you can collapse a for loop that looks like this:

一旦您拥有一个返回序列中的下一个事物的对象,您就可以折叠如下所示的 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

into this:

进入这个:

myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x

Notice that there is nowhere where we have code that gets the next value of i because range(10) is an object that FOLLOWS the iterator protocol, and the list comprehension is a construct that USES the iterator protocol.

请注意,我们没有任何地方可以获取 i 的下一个值,因为 range(10) 是遵循迭代器协议的对象,而列表推导式是使用迭代器协议的构造。

You can also USE the iterator protocol directly. For instance, when writing scripts to process CSV files, I often write this:

你也可以直接使用迭代器协议。例如,在编写处理 CSV 文件的脚本时,我经常这样写:

mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
    # do something with the row.

I am using the iterator directly by calling next()to skip the header row, then using it indirectly via the builtin inoperator in the forstatement.

我通过调用next()跳过标题行直接使用迭代器,然后通过语句中的内置in运算符间接使用它for