2009-11-11 17 views

答えて

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)を扱わなければならないので、適当ではない。)

+1

@pantsgolemは、Python 3では、iterator以外で呼び出したときに 'next()'が 'TypeError'を呼び出すと指摘しました。私はこの回答を編集して 'AttributeError'を捕まえ、' TypeError'としてそれを再現しました。 (私はこれが良いStackOverflowエチケットであることを願っています;これは私が他人の答えを編集した初めてのことです!) – steveha

+0

さらに重要なことに、2.6のnext()はその場合にTypeErrorを発生させます。それを修正することはできますが、それを含めるように編集することは私にはうまくいきます。 –

6

R.ペイトが良いを持っているようです回答。あなたは、Pythonのさまざまなバージョンで実行するコードを書いている場合は、あなたが定義を条件付きすることができます:1つの余分追加するベル

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

あなたはどのような場合にnextが定義されていることの方法がありますが、使用しています利用可能な場所に実装されています。私は私のコードを使用して、その後別の場所で、モジュールにこの定義を置くことができるように

は私がnext = nextを使用します。

from backward import next 
+0

次のテストはできませんか?例えば。 'try:next; except ... ' –

+1

これはプロジェクトにこれらの定義を含める方法と関係があります。私は答えをうかがった。 –

2

簡単な方法:tryにそれを置くことについての

import operator 

next = operator.methodcaller("next") 

ネッドの提案Python 3では、イテレータでない場合にnext()を呼び出すとTypeErrorが呼び出されますが、このバージョンではAttributeErrorが発生します。

編集:決して気にしないでください。 stevehaが指摘するように、operator.methodcaller()は2.6で導入されましたが、これは残念です。

+0

'.next()'メソッドを持たないオブジェクトに対して 'next()'を呼び出すときに 'AttributeError'を発生させるためにR.Pateの答えを編集しました。 – steveha

+0

'operator.methodcaller()'は面白そうですが、Python 2.6で追加されました。 R.Pateの答えは、イテレータを使ってPythonで動くはずです。 – steveha

関連する問題