python中的next()方法:定义是否正确?

时间:2013-09-11 00:22:44

标签: python python-2.7 iterator

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()方法从迭代器中检索下一个项目。如果给定default,则在迭代器耗尽时返回,否则引发StopIteration。

执行此方法时,迭代器是否移动到对象的第二个元素(调用该方法?)时,是否缺少解释?

2 个答案:

答案 0 :(得分:3)

你所说的并不是next function,而是每个迭代器如何实现next method。并且,虽然许多迭代器在您调用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)上调用10时,next返回的迭代器只会为您提供10。你可以将它想象为一个无限长度列表上的迭代器,其元素都是class RepeatIterator(object): def __init__(self, value): self.value = value def next(self): return self.value ,但这显然不是它真正起作用的方式。它实际上是这样的:

10

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


顺便说一句,在Python 3中更容易讨论,你可以使用__next__函数调用next方法,而不是iter(i)方法。当然,Python 3的方式遵循与其他特殊方法相同的模式 - i.__iter__()调用getattr(obj, attr)obj.__getattr__(attr)调用next(i)i.__next__()调用{{1 }}

答案 1 :(得分:1)

你似乎习惯于像C ++这样的迭代器,它们是泛化指针。 Python中的迭代器没有“取消引用”和“前进”操作;他们已经“得到了下一件事”,其中“下一件事”就是在迭代器出现的前一件事之后的事实,这是因为它是下一件事。

文档可以明确声明操作会更改迭代器的状态。这可能更清楚,但在字数和信息重复方面存在权衡。如果你按照next方法的链接,你可以看到完整的迭代器协议,其中只有__iter__next,这清楚地表明没有单独的操作推进迭代器。但是文档仍然没有明确说明next推进了迭代器。