2010-06-11 17 views

उत्तर

37

अजगर 2.6 या बेहतर में, इस तरह व्यवहार जांच के लिए तैयार किया गया है में मुहावरा के साथ एक "सदस्यता की जांच" है मानक पुस्तकालय की collections मॉड्यूल में सार आधार वर्ग:

>>> import collections 
>>> isinstance('ciao', collections.Iterable) 
True 
>>> isinstance(23, collections.Iterable) 
False 
>>> isinstance(xrange(23), collections.Iterable) 
True 

दरअसल, चेक की इस तरह की नई सार आधार वर्ग के लिए प्रमुख डिजाइन कारण (एक दूसरे महत्वपूर्ण एक कुछ में "mixin कार्यक्षमता" प्रदान करना है मामले, यही कारण है कि वे एबीसी रथ हैं सिर्फ इंटरफ़ेस की तुलना में - लेकिन यह collections.Iterable पर लागू नहीं होता है, यह मौजूद है ताकि isinstance या issubclass के साथ ऐसे चेक की अनुमति मिल सके)। एबीसी उन वर्गों को अनुमति देता है जो वास्तव में उनसे उपबंधों के रूप में "पंजीकृत" होने के लिए उत्तराधिकारी नहीं होते हैं, ताकि इस तरह के वर्ग एबीसी के ऐसे चेक के लिए "उप-वर्ग" हो सकें; और, वे इस मामले में विशेष तरीकों (__iter__) के लिए आंतरिक रूप से सभी आवश्यक चेक निष्पादित कर सकते हैं, इसलिए आपको यह नहीं करना है।

आप अजगर के पुराने रिलीज के साथ आ रही है, "यह अनुमति से माफी पूछने के लिए बेहतर है":

def isiterable(x): 
    try: iter(x) 
    except TypeError: return False 
    else: return True 

लेकिन यह है कि के रूप में तेजी से और नए दृष्टिकोण के रूप में संक्षिप्त नहीं है।

ध्यान दें कि इस विशेष मामले के लिए आप अक्सर विशेष-केस स्ट्रिंग्स (जो कि पुनरावृत्त होते हैं लेकिन अधिकांश एप्लिकेशन संदर्भ "स्केलर्स" के रूप में व्यवहार करना चाहते हैं) के लिए चाहते हैं।

def reallyiterable(x): 
    return not isinstance(x, basestring) and isinstance(x, collections.Iterable) 

संपादित: के रूप में एक टिप्पणी में कहा, सवाल यह है कि पर केंद्रित है - उदाहरण के लिए जो कुछ भी दृष्टिकोण आप iterableness जाँच करने के लिए, अगर आप इस तरह के विशेष आवरण की जरूरत है सिर्फ isinstance(x, basestring) का चेक पहले जोड़ें का उपयोग कर रहे एक ऑब्जेक्ट एक iter *** ator *** है, यह है कि यह *** है *** सक्षम है (सभी iterators पुनरावृत्त हैं, लेकिन इसके विपरीत नहीं - सभी iterables इटेटर नहीं हैं)। isinstance(x, collections.Iterator) विशेष रूप से उस स्थिति की जांच करने के लिए बिल्कुल समान तरीका है।

+9

प्रश्न पूछते हैं कि कोई वस्तु एक पुनरावर्तक है, भले ही यह पुनरावृत्त न हो। इसलिए आपको संग्रह का उपयोग करना चाहिए। संग्रह के बजाय इटरेटर। इटेबल –

+0

@ डेव, दाएं, मुझे स्पष्टीकरण देने के लिए संपादित करें। –

9

यदि ऑब्जेरेटर प्रोटोकॉल लागू होता है तो एक ऑब्जेक्ट पुनरावर्तनीय होता है।
आप के साथ __iter__() विधि की उपस्थिति की जांच कर सकता:

hasattr(object,'__iter__') 

पायथन 2.x में इस दृष्टिकोण str वस्तुओं और यूनिकोड, xrange, बफर जैसे अन्य अंतर्निहित अनुक्रम प्रकार याद करते हैं। यह अजगर में काम करता है 3.

एक और तरीका है आईटीईआर विधि के साथ यह परीक्षण करने के लिए है:

try: 
    iter(object) 
except TypeError: 
    #not iterable 
+1

इटरेटर बनाना महंगा हो सकता है जबकि विशेषता अस्तित्व की जांच हमेशा * तेज * होती है। –

4

पुनरावर्तक होना करने के लिए एक वस्तु तीन परीक्षणों से गुजरना होगा:

  • obj एक __iter__ विधि
  • obj एक next विधि (या __next__ अजगर 3 में)
  • obj.__iter__() रिटर्न है obj

तो, एक रोल-अपना स्वयं का परीक्षण होगा इस तरह दिखें:

def is_iterator(obj): 
    if (
      hasattr(obj, '__iter__') and 
      hasattr(obj, 'next') and  # or __next__ in Python 3 
      callable(obj.__iter__) and 
      obj.__iter__() is obj 
     ): 
     return True 
    else: 
     return False 
+0

'obj .__ iter __()' को कॉल करने का जोखिम कुछ बदलने का जोखिम चलाएगा? –

+0

@ बॉबस्टिन-विस्बीबोन: केवल अगर वस्तु छोटी है। –

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

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