याद रखें कि पायथन में हम "डक टाइपिंग" का उपयोग करना चाहते हैं। तो, कुछ भी जो सूची की तरह काम करता है, उसे सूची के रूप में माना जा सकता है। इसलिए, सूची के प्रकार की जांच न करें, बस यह देखें कि क्या यह सूची की तरह काम करता है।
लेकिन तार एक सूची की तरह भी काम करते हैं, और अक्सर वह नहीं है जो हम चाहते हैं। ऐसे समय होते हैं जब यह एक समस्या है! तो, एक स्ट्रिंग के लिए स्पष्ट रूप से जांचें, लेकिन फिर बतख टाइपिंग का उपयोग करें।
यहाँ एक समारोह है जो मैंने मनोरंजन के लिए लिखा है। यह repr()
उस कोण का एक विशेष संस्करण है जो कोण कोष्ठक ('<', '>') में किसी भी अनुक्रम को प्रिंट करता है।
def srepr(arg):
if isinstance(arg, basestring): # Python 3: isinstance(arg, str)
return repr(arg)
try:
return '<' + ", ".join(srepr(x) for x in arg) + '>'
except TypeError: # catch when for loop fails
return repr(arg) # not a sequence so just return repr
यह साफ और सुरुचिपूर्ण है, कुल मिलाकर। लेकिन वह isinstance()
चेक वहां क्या कर रहा है? यह एक हैक की तरह है। लेकिन यह जरूरी है।
यह फ़ंक्शन किसी सूची की तरह काम करने वाली चीज़ों पर खुद को पुनरावर्ती कहता है। यदि हम स्ट्रिंग को विशेष रूप से नहीं संभालते हैं, तो यह एक सूची की तरह माना जाएगा, और एक समय में एक वर्ण को विभाजित करेगा। लेकिन फिर पुनरावर्ती कॉल प्रत्येक चरित्र को एक सूची के रूप में मानने की कोशिश करेगा - और यह काम करेगा! यहां तक कि एक-चरित्र स्ट्रिंग सूची के रूप में काम करता है! जब तक स्टैक ओवरफ्लो नहीं हो जाता तब तक फ़ंक्शन स्वयं को पुनरावर्ती रूप से कॉल करता रहेगा।
इस तरह के कार्य, जो कि किए जाने वाले कार्य को तोड़ने वाले प्रत्येक पुनरावर्ती कॉल पर निर्भर करते हैं, को विशेष-केस स्ट्रिंग्स को करना पड़ता है - क्योंकि आप एक-वर्ण स्ट्रिंग के स्तर से नीचे एक स्ट्रिंग को नहीं तोड़ सकते हैं, और यहां तक कि एक भी -च्रेकर स्ट्रिंग एक सूची की तरह काम करता है।
नोट: try
/ except
हमारे इरादों को व्यक्त करने का सबसे साफ तरीका है। लेकिन अगर यह कोड किसी तरह से समय के लिए महत्वपूर्ण था, तो हम यह देखना चाहेंगे कि क्या arg
यह अनुक्रम है या नहीं। प्रकार का परीक्षण करने के बजाय, हमें शायद व्यवहार का परीक्षण करना चाहिए। यदि यह एक .strip()
विधि है, तो यह एक स्ट्रिंग है, इसलिए इसे एक अनुक्रम न मानें; अन्यथा, यदि यह अनुक्रमणीय या पुन: प्रयोज्य है, तो यह एक अनुक्रम है:
def is_sequence(arg):
return (not hasattr(arg, "strip") and
hasattr(arg, "__getitem__") or
hasattr(arg, "__iter__"))
def srepr(arg):
if is_sequence(arg):
return '<' + ", ".join(srepr(x) for x in arg) + '>'
return repr(arg)
संपादित करें: मैंने मूल रूप से एक चेक के साथ ऊपर लिखा था, __getslice__()
लेकिन मैंने देखा कि collections
मॉड्यूल प्रलेखन में, दिलचस्प विधि है __getitem__()
; इससे समझ में आता है, कि आप किसी वस्तु को कैसे अनुक्रमित करते हैं। यह अधिक मौलिक लगता है __getslice__()
इसलिए मैंने उपरोक्त परिवर्तन किया।