0
with open('some.txt', 'r') as input_file:
    #read the file starting from the second line.
    for line in input_file:
        print line

代码是不言自明的。但是,我不知道为什么仅通过阅读有关该next()方法的文档就可以工作,因为这是我第一次使用该方法。官方文档将方法描述为:

next(iterator[, default])

通过调用其 next() 方法从迭代器中检索下一项。如果给出默认值,则在迭代器耗尽时返回,否则引发 StopIteration。

解释是不是缺少了执行此方法时,将迭代器移动到调用该方法的对象的第二个元素的部分?

4

2 回答 2

3

您所说的实际上并不取决于next函数,而是取决于每个迭代器如何实现其next方法。而且,虽然许多迭代器在您调用时会“提前” next,但他们不必这样做。


原型迭代器是指向某个可迭代对象中某个位置的虚拟“指针”,它们的next方法返回迭代器当前指向的值,并将其前进以指向可迭代对象中的下一个值。

例如,考虑通过调用iter列表返回的迭代器。第一次调用next(i)返回元素 0,然后下一次调用返回元素 1,依此类推。你可以像这样模拟它的行为:

class ListIterator(object):
    def __init__(self, lst):
        self.lst = lst
        self.idx = 0
    def next(self):
        try:
            value = self.lst[self.idx]
        except IndexError:
            raise StopIteration
        self.idx += 1
        return value

显然,这是通常的情况,因此得名next.


但是你可以很容易地创建一个不能以这种方式工作的迭代器——不仅仅是作为某种病态类型来证明一个观点,而是实际有用的迭代器。

例如,查看itertools.repeat. 每次调用它时,返回的迭代器itertools.repeat(10)都会给你。你可以把它想象成一个无限长列表的迭代器,它的元素都是 all ,但这显然不是它真正的工作方式。它实际上是这样工作的:10next10

class RepeatIterator(object):
    def __init__(self, value):
        self.value = value
    def next(self):
        return self.value

其他迭代器通过动态计算值、从套接字中拉出缓冲区等来工作。您总是可以找到一种方法将任何迭代器视为指向某种虚拟序列中某个位置的指针,就像10s 的虚拟无限列表,但这通常是一个延伸,在这些情况下,考虑真正发生的事情会更有帮助——调用next方法。


顺便说一句,这在 Python 3 中更容易讨论,在那里你有一个next调用__next__方法的函数,而不是一个next方法。当然,Python 3 的方式与其他特殊方法遵循相同的模式——<code>iter(i) 调用i.__iter__()getattr(obj, attr)调用obj.__getattr__(attr)next(i)调用i.__next__()

于 2013-09-11T00:51:20.573 回答
1

您似乎习惯了来自 C++ 之类的迭代器,它们是通用指针。Python 中的迭代器没有“取消引用”和“提前”操作;他们有“获得下一件事”,其中“下一件事”是从迭代器中出来的上一件事情之后的事情这一事实暗示了它是下一件事情的事实。

文档可以明确声明该操作会更改迭代器的状态。这可能更清楚,但在字数和信息重复方面存在折衷。如果您点击该next方法的链接,您可以看到完整的迭代器协议,特别是其中只有__iter__next,这清楚地表明没有单独的操作来推进迭代器。不过,该文档仍然没有明确说明会next推进迭代器。

于 2013-09-11T00:26:26.117 回答