Python 2.6+ 和 3.* 有 next(),但 pre-2.6 只提供 object.next 方法。有没有办法在 pre-2.6 中获得 next() 样式;也许是一些“def next():”构造?
问问题
568 次
3 回答
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)
)
于 2009-11-11T16:39:56.267 回答
6
R. Pate 似乎有一个很好的答案。一个额外的补充:如果您正在编写代码以在许多不同版本的 Python 上运行,您可以对定义进行条件化:
try:
next = next
except NameError:
def next():
# blah blah etc
这样你next
在任何情况下都已经定义了,但是你使用的是可用的内置实现。
我使用next = next
以便我可以将此定义放在一个模块中,然后在我的代码中的其他地方使用:
from backward import next
于 2009-11-11T16:43:42.240 回答
2
更简单的方法:
import operator
next = operator.methodcaller("next")
Ned 关于将它放在一个try
块中的建议在这里也有效,但如果你要走那条路,一个小注意事项:在 Python 3 中,调用next()
非迭代器会引发 a TypeError
,而这个版本会引发 an AttributeError
。
编辑:没关系。正如 steveha 指出的那样,operator.methodcaller()
仅在 2.6 中引入,这是一种耻辱。
于 2009-11-11T19:28:02.097 回答