Python 2.6之前的def next()?(替代object.next方法)

5 投票
3 回答
591 浏览
提问于 2025-04-15 15:54

Python 2.6 及以上版本和 3.* 版本都有一个叫 next() 的功能,但在 2.6 之前的版本只能用对象的 next 方法。有没有办法在 2.6 之前的版本里实现 next() 这种风格呢?比如说,能不能用某种方式定义一个 "def next():" 的函数?

3 个回答

2

更简单的方法:

import operator

next = operator.methodcaller("next")

Ned提到的把它放在一个try块里的建议在这里也适用,不过如果你选择这样做,有一点小提醒:在Python 3中,对一个不是迭代器的对象调用next()会引发一个TypeError错误,而这个版本则会引发一个AttributeError错误。

编辑:没关系。正如steveha指出的,operator.methodcaller()这个功能是在2.6版本中才引入的,真可惜。

6

R. Pate 的回答看起来很不错。这里再补充一点:如果你写的代码要在很多不同版本的 Python 上运行,你可以根据条件来定义这个函数:

try:
    next = next
except NameError:
    def next():
        # blah blah etc

这样的话,无论怎样你都有 next 这个函数的定义,但在可以使用内置实现的情况下,你会使用内置的版本。

我使用 next = next 这样可以把这个定义放在一个模块里,然后在我代码的其他地方使用:

from backward import next
11
class Throw(object): pass
throw = Throw() # easy sentinel hack
def next(iterator, default=throw):
  """next(iterator[, default])

  Return the next item from the iterator. If default is given
  and the iterator is exhausted, it is returned instead of
  raising StopIteration.
  """
  try:
    iternext = iterator.next.__call__
    # this way an AttributeError while executing next() isn't hidden
    # (2.6 does this too)
  except AttributeError:
    raise TypeError("%s object is not an iterator" % type(iterator).__name__)
  try:
    return iternext()
  except StopIteration:
    if default is throw:
      raise
    return default

(throw = object() 这种写法也可以,但在查看文档时效果更好,比如用 help(next)。用 None 不太合适,因为你需要把 next(it)next(it, None) 处理得不一样。)

撰写回答