2009-11-11 9 views
5

पायथन 2.6+ और 3. * के पास अगला() है, लेकिन प्री-2.6 केवल object.next विधि प्रदान करता है। अगली() शैली को पूर्व-2.6 में प्राप्त करने का कोई तरीका है; कुछ "अगला अगला():" शायद निर्माण?def अगला()? (object.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) अलग ढंग से इलाज करना होगा।)

+1

@ पैंट्सगोलेम ने इंगित किया कि पाइथन 3 में, 'अगला()' 'टाइपरर' उठाता है जब आप इसे गैर-पुनरावर्तक पर कॉल करते हैं। मैंने इस विशेषता को 'एट्रिब्यूट एरर' पकड़ने के लिए संपादित किया और इसे 'टाइप एरर' के रूप में फिर से उठाया। (मुझे आशा है कि यह अच्छा स्टैक ओवरफ्लो शिष्टाचार है; यह पहली बार है जब मैंने किसी और के जवाब को संपादित किया है!) – steveha

+0

अधिक महत्वपूर्ण बात यह है कि 2.6 में अगला() उस मामले में TypeError उठाता है। इसे शामिल करने के लिए संपादन मेरे द्वारा ठीक है, हालांकि मैंने raise को संशोधित किया है। –

6

आर पेट एक अच्छा है करने के लिए लगता है जवाब। एक अतिरिक्त घंटी जोड़ने के लिए: यदि आप अजगर के कई अलग अलग संस्करणों पर चलने के लिए कोड लिख रहे हैं, तो आप परिभाषा conditionalize कर सकते हैं:

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

इस तरह आप next किसी भी मामले में परिभाषित किया गया है, लेकिन आप का उपयोग कर रहे कार्यान्वयन में बनाया गया जहां यह उपलब्ध है।

मैं next = next उपयोग करती हैं इसलिए है कि मैं अपने कोड का उपयोग में एक मॉड्यूल में इस परिभाषा रख सकते हैं, तो कहीं और:

from backward import next 
+0

परीक्षण अभी अगला नहीं हो सकता है? जैसे कोशिश करो: अगला; सिवाय इसके कि ... ' –

+1

इसे मेरे प्रोजेक्ट में इन परिभाषाओं को शामिल करने के तरीके से करना है। मैंने जवाब उतार दिया है। –

2

सरल विधि:

import operator 

next = operator.methodcaller("next") 

नेड की एक try में डालने के बारे में सुझाव ब्लॉक यहां भी काम करता है, लेकिन यदि आप उस मार्ग पर जा रहे हैं, तो एक मामूली नोट: पायथन 3 में, गैर-इटरेटर पर next() पर कॉल करने से TypeError बढ़ जाता है, जबकि यह संस्करण AttributeError उठाएगा।

संपादित करें: कभी भी ध्यान न दें। स्टीव बताते हैं, operator.methodcaller() केवल 2.6 में पेश किया गया था, जो शर्म की बात है।

+0

मैंने किसी ऑब्जेक्ट पर 'अगला()' को कॉल करते समय 'AttributeError' को बढ़ाने के लिए R.Pate के उत्तर को संपादित किया है जिसमें' .next() 'विधि नहीं है। – steveha

+0

'operator.methodcaller() 'दिलचस्प लग रहा है, लेकिन इसे पायथन 2.6 में जोड़ा गया था। आर। पेट का जवाब किसी भी पायथन में इटरेटर के साथ काम करना चाहिए। – steveha

संबंधित मुद्दे