def next() for Python pre-2.6? (instead of object.next method)
Python 2.6+ and 3.* have next(), but pre-2.6 only offers the object.next method. Is there a way to get the next() style in pre-2.6; some "def next():" construction开发者_如何转开发 perhaps?
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()
works too, but this generates better docs when inspecting, e.g. help(next)
. None
is not suitable, because you must treat next(it)
and next(it, None)
differently.)
R. Pate seems to have a good answer. One extra bell to add: if you're writing code to run on many different versions of Python, you can conditionalize the definition:
try:
next = next
except NameError:
def next():
# blah blah etc
That way you have next
defined in any case, but you're using the built in implementation where it's available.
I use next = next
so that I can put this definition in a module, then elsewhere in my code use:
from backward import next
Simpler method:
import operator
next = operator.methodcaller("next")
Ned's suggestion about putting it in a try
block works here as well, but if you're going to go that route, one minor note: in Python 3, calling next()
on a non-iterator raises a TypeError
, whereas this version would raise an AttributeError
instead.
Edit: Never mind. As steveha points out, operator.methodcaller()
was only introduced in 2.6, which is a shame.
精彩评论