2009-11-11 14 views

cevap

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() çok çalışır, ancak None uygun değildir mesela help(next)., Teftiş yaparken farklı next(it) ve next(it, None) tedavi gerekir çünkü bu, daha iyi dokümanlar üretir.)

+1

@pantsgolem, Python 3'te 'next()' ifadesinin, non-iterator'da çağırdığınızda 'TypeError 'öğesini yükselttiğine dikkat çekti. AttributeError 'ı yakalamak ve' TypeError 'olarak yeniden yükseltmek için bu cevabı düzenledim. (Bu iyi StackOverflow görgü umut; bu başkasının cevap düzenledikten ilk kez!) – steveha

+0

Daha da önemlisi, 2.6() sonraki bu durumda TypeError yükseltir. Yükseltmeyi değiştirdim olsa da, benim tarafımdan düzenlemek benim için iyi. –

6

R. Pate iyi gibi görünüyor Cevap. Eğer Python birçok farklı sürümlerinde çalışacak kod yazıyorsanız, sen tanımını conditionalize edebilirsiniz: Bir ilave çan eklemek için

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

Eğer her durumda tanımlanan next aynı olur, ancak kullandığınız mevcut olduğu yerde uygulamaya geçirilmiştir. Benim kodu kullanılıyor sonra başka bir yerde, bir modülde bu tanımı koymak, böylece

Ben next = next kullanın:

from backward import next 
+0

Test sadece sıradaki olamaz mı? Örneğin. deneyin: sonraki; hariç ... ' –

+1

Bu tanımları projeme dahil etme şeklimizle ilgisi var. Cevabı ben verdim. –

2

basit yöntemi: Bir try koyarak yaklaşık

import operator 

next = operator.methodcaller("next") 

Ned'in öneri blok burada da çalışır, ancak bu rotaya gidecekseniz, küçük bir not: Python 3'te, next()'u yineleyici olmayan bir numaraya çağırmak, TypeError'u yükseltirken, bu sürüm bunun yerine AttributeError'u yükseltecektir.

Düzenleme: boşver. Steveha'nın işaret ettiği gibi, operator.methodcaller() sadece 2.6'da tanıtıldı, bu utanç verici.

+0

Bir '.next()' yöntemine sahip olmayan bir nesnede 'next()' yi çağırırken 'AttributeError 'öğesini yükseltmek için R.Pate'in yanıtını düzenledim. – steveha

+0

'operator.methodcaller()' ilginç görünüyor, ancak Python 2.6'da eklendi. R.Pate'in cevabı, yineleyici ile herhangi bir Python'da çalışmalıdır. – steveha

İlgili konular