返回介绍

手动迭代:iter 和 next

发布于 2024-01-29 22:24:16 字数 1913 浏览 0 评论 0 收藏 0

为了支持手动迭代代码(用较少的录入),Python 3.0还提供了一个内置函数next,它会自动调用一个对象的__next__方法。给定一个可迭代对象X,调用next(X)等同于X.__next__(),但前者简单很多。例如,对于文件的任何一种形式都可以使用:

从技术角度来讲,迭代协议还有一点值得注意。当for循环开始时,会通过它传给iter内置函数,以便从可迭代对象中获得一个迭代器,返回的对象含有需要的next方法。如果我们看看for循环内部如何处理列表这类内置序列类型的话,就会变得一目了然了。

最初的一步对于文件来说不是必需的,因为文件对象就是自己的迭代器。也就是说,文件有自己的__next__方法,因此不需要像这样返回一个不同的对象:

列表以及很多其他的内置对象,不是自身的迭代器,因为它们支持多次打开迭代器。对这样的对象,我们必须调用iter来启动迭代:

尽管Python迭代工具自动调用这些函数,我们也可以使用它们来手动地应用迭代协议。如下的交互展示了自动和手动迭代之间的对等性[1]

要理解这段代码,你需要知道,try语句运行一个动作并且捕获在运行过程中发生的异常(我们将在本书第七部分深入介绍异常)。还应该注意,for循环和其他的迭代环境有时候针对用户定义的类不同地工作,重复地索引一个对象而不是运行迭代协议。等到我们在第29章中学习运算符重载的时候,再介绍这一内容。

注意:版本差异提示:在Python 2.6中,迭代方法叫做X.next()而不是X.__next__()。为了可移植性,next(X)内置函数在Python 2.6中也是可用的(但在更早的版本中不可以),并且,调用Python 2.6的X.next()而不是Python 3.0的X.__next__()。在Python 2.6中所有其他方式中,迭代都是一样地工作的,只是在手动迭代中直接使用X.next()或next(X),而不是Python 3.0的X.__next__()。在Python 2.6之前的版本中,使用手动X.next()调用而不是next(X)。

[1]从技术上讲,for循环调用内部等价的I.__next__,而不是这里所使用的next(I)。这两者之间几乎没有区别,但是,我们将在下一小节中看到,Python 3.0中有一些内置的对象(例如os.popen的结果)支持前者而不支持后者,但仍然可以在for循环中迭代。手动的迭代通常可以使用任何一种调用形式。如果你关注详细情况,Python 3.0中的os.popen结果已经用subprocess模块和一个包装类重新实现,在Python 3.0中,其__getattr__方法不再针对next内置函数所做出的显式__next__获取而调用,而是针对按名称的显式获取而调用,这是我们将在第37章和第38章中学习的一个Python 3.0的修改,它似乎也用到了某些标准库代码。还是在Python 3.0中,相关的Python 2.6调用os.popen2/3/4不再可用,而是使用带有相应参数的subprocess.Popen(参见Python 3.0库手册可以了解新的必需的代码)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文