परीक्षण अगर एक चर एक सूची या टपल है


234

अजगर में, परीक्षण करने का सबसे अच्छा तरीका क्या है यदि एक चर में एक सूची या एक टपल है? (अर्थात एक संग्रह)

क्या isinstance()उतनी ही बुराई है जितनी यहाँ सुझाई गई है? http://www.canonical.org/~kragen/isinstance/

अद्यतन: मैं एक स्ट्रिंग से एक सूची को अलग करना चाहता हूं सबसे आम कारण यह है कि जब मेरे पास अनिश्चित काल के गहरे घोंसले के पेड़ / तारों की सूची की सूचियों की डेटा-संरचना आदि हैं, जो मैं एक पुनरावर्ती एल्गोरिथ्म के साथ खोज रहा हूं और मुझे इसकी आवश्यकता है यह जानने के लिए कि मैंने "पत्ता" नोड्स को कब मारा है।


72
मोटे तौर पर टाइप-चेकिंग को बुराई के रूप में खारिज करना थोड़ा कठिन है। यह भाषा का हिस्सा है। यदि यह बहुत बुरा है, तो किसी को इसे हटाने के लिए पीईपी लिखना चाहिए।
एडम क्रॉसलैंड

4
@ एडम क्रॉसलैंड: "यह भाषा का हिस्सा है।" जैसे शून्य से विभाजन। यह परिहार्य है। इस मामले में, अतिरिक्त जानकारी के बिना, यह शायद पूरी तरह से अनावश्यक है। पायथन में अधिकांश प्रकार की जाँच अनावश्यक है। चूंकि सभी बेकार नहीं हैं, इसलिए कुछ प्रकार की जाँच की आवश्यकता है। लेकिन इसका मतलब यह नहीं है कि यह उपयोगी, मूल्यवान, या एक अच्छा विचार है।
S.Lott

11
तो आप कह रहे हैं कि कुछ प्रकार की जाँच की आवश्यकता है, लेकिन इसके बावजूद, यह बेकार, बेकार और एक बुरा विचार है। क्षमा करें, इससे कोई मतलब नहीं है।
ग्लेन मेनार्ड

18
"XXX बुराई है" बुरी तरह से कल्पना की गई है, "जिस तरह से आप XXX को करने के लिए कह रहे हैं, उसके लिए भ्रामक आशंका है, आपको पता नहीं चलता है कि यह वास्तव में कब इस्तेमाल किया जाना चाहिए, और आप लगभग निश्चित रूप से कुछ और चाहते हैं"। यहां सबसे अधिक संभावना यही है।
ग्लेन मेनार्ड

2
मैंने इसे व्यापक रूप से बुराई के रूप में खारिज नहीं किया। मैंने इस बारे में एक लघु निबंध लिखा है कि यह कब बुराई है और कब उचित है। यह निबंध कई चीजें हो सकती हैं - सही, गलत, स्पष्ट, अस्पष्ट, सुखद, उबाऊ - लेकिन एक चीज यह तकनीक का व्यापक खारिज नहीं है।
Kragen जेवियर सीटकेर

जवाबों:


101

isinstanceजरूरत पड़ने पर आगे बढ़ें और उपयोग करें । यह कुछ हद तक बुराई है, क्योंकि यह कस्टम अनुक्रमों, पुनरावृत्तियों और अन्य चीजों को बाहर करता है जिनकी आपको वास्तव में आवश्यकता हो सकती है। हालांकि, कभी-कभी आपको अलग तरह से व्यवहार करने की आवश्यकता होती है यदि कोई, उदाहरण के लिए, एक स्ट्रिंग पास करता है। मेरी पसंद वहाँ स्पष्ट रूप से strया के लिए जाँच करने के लिए किया जाएगा unicode:

import types
isinstance(var, types.StringTypes)

एनबी के types.StringTypeलिए गलती मत करो types.StringTypes। उत्तरार्द्ध शामिल है strऔर unicodeवस्तुओं।

typesमॉड्यूल, कई द्वारा माना जाता है सिर्फ वस्तु के प्रकार के खिलाफ सीधे जाँच के पक्ष में अप्रचलित इसलिए यदि आप बल्कि ऊपर का उपयोग नहीं हैं, तो आप वैकल्पिक रूप से स्पष्ट रूप से के खिलाफ जांच कर सकते हैं strऔर unicode, इस तरह:

isinstance(var, (str, unicode)):

संपादित करें:

अभी भी बेहतर है:

isinstance(var, basestring)

अंत संपादित करें

इन दोनों में से किसी के बाद, आप व्यवहार में वापस आ सकते हैं जैसे कि आप एक सामान्य अनुक्रम प्राप्त कर रहे हों, गैर-अनुक्रमों को उचित अपवाद देने दें।

यह देखें कि टाइप चेकिंग के बारे में "बुराई" यह नहीं है कि आप एक निश्चित प्रकार की वस्तु के लिए अलग तरह से व्यवहार करना चाहते हैं, यह है कि आप कृत्रिम रूप से अपने काम को अप्रत्याशित वस्तु प्रकारों के साथ सही काम करने से प्रतिबंधित करते हैं जो अन्यथा सही काम करेंगे। यदि आपके पास एक अंतिम कमबैक है जो टाइप-चेक नहीं किया गया है, तो आप इस प्रतिबंध को हटा दें। यह ध्यान दिया जाना चाहिए कि बहुत अधिक प्रकार की जाँच एक कोड गंध है जो इंगित करती है कि आप कुछ रीफ़ैक्टरिंग करना चाहते हैं, लेकिन इसका मतलब यह नहीं है कि आपको इसे गेटो से बचना चाहिए।


2
प्रकार मॉड्यूल एक ऐतिहासिक कलाकृति का एक सा है। जैसा कि docs.python.org/dev/library/types.html#module-types पर बताया गया है, यदि आपको वास्तव में उस strप्रकार की जांच करनी चाहिए, जिसका उपयोग आपको सीधे सीधे करना चाहिए, इसके बजाय इसका उपयोग केवल इसके types.StringTypeलिए एक उपनाम है। लेकिन मुझे नहीं लगता कि यह उत्तर पूछे गए प्रश्न का उत्तर देता है, क्योंकि यह "एक संग्रह" के बारे में था। जब तक आप एक अजगर नए का उपयोग कर रहे हैं, तब तक abcमॉड्यूल है कि आप के isinstanceलिए जाँच करने के लिए उपयोग कर सकते हैं कुछ नहीं है , और फिर भी मैं अगर संभव हो तो चेक से बचने की सलाह दूंगा।
फेज

1
assert isinstance(u'abc', str) == False। मैं सहमत हूं कि typesमॉड्यूल का उपयोग करने के बजाय सीधे प्रकार के खिलाफ जांच करना बेहतर है , लेकिन types.StringTypesकुछ ऐसा करता है जो strऐसा नहीं करता है: यह सत्य के लिए strऔर unicodeवस्तुओं को लौटाता है । मैं एक विकल्प के रूप में एक दोहरी जांच की पेशकश करने के लिए अपनी प्रतिक्रिया संपादित करूंगा।
jcdyer

1
मुझे लगता है कि मैंने सीधे संग्रह के लिए जाँच के सवाल का जवाब नहीं दिया, लेकिन जो वास्तविक प्रश्न पूछा गया था, वह " isinstanceबुराई है?" और मैंने एक काउंटर उदाहरण दिया जो (1) का एक गैर-दुष्ट उपयोग है isinstance, क्योंकि फॉलबैक होने का अर्थ है कि यह टकसाल को नहीं तोड़ता है, और (2) एक बहुत ही आम प्रेरणा के लिए एक अच्छा समाधान है जो लोग जांचना चाहते हैं कि क्या है कुछ एक है ( listया tupleउन्हें तार से अलग करने के लिए)।
jcdyer

मैं सहमत हूँ, इस चेतावनी के साथ कि अक्सर यह कस्टम प्रकारों के लिए उपयोगी होता है जैसे कि तार भी। लेकिन पायथन का OO केवल इतना आगे जाता है ...
Kragen Javier Sitaker

क्या class Foo(str): passतुम क्या चाहते हो?
jcdyer

567
if type(x) is list:
    print 'a list'
elif type(x) is tuple:
    print 'a tuple'
else:
    print 'neither a tuple or a list'

1
काम नहीं लगता है: टाइप ([]) ==> सूची; type ([]) लिस्ट ===> फाल्स
स्टेन

3
पायथन में 2.7.5: type([]) is listरिटर्नTrue
डेविड गीगर

54
type(x) in [list,tuple]छोटा है।
एलेक्स होल्कोम्बे

अगर x और टाइप (x) सूची है: [] बेमेल से बचने के लिए
केनिचि शिबाता

मुझे इतना नीचे स्क्रॉल करना पड़ा। : डी
ऋत्विक

38

जब isinstanceतक यह बेमानी न हो, तब तक उपयोग करने में कुछ भी गलत नहीं है। यदि एक चर केवल एक सूची / ट्यूपल होना चाहिए तो इंटरफ़ेस का दस्तावेज़ करें और बस इसे इस तरह से उपयोग करें। अन्यथा एक जाँच पूरी तरह से उचित है:

if isinstance(a, collections.Iterable):
    # use as a container
else:
    # not a container!

इस प्रकार के चेक में कुछ अच्छे उपयोग के मामले हैं, जैसे कि मानक स्ट्रिंग शुरुआत / अंत के तरीकों के साथ (हालांकि ये सटीक होने के लिए सीपीयू में सी में कार्यान्वित किए जाते हैं यह देखने के लिए कि क्या यह एक तुक है - यह एक तरह से अधिक है इस समस्या को हल करने के लिए, जैसा कि आप लिंक लेख में बताया गया है)।

एक स्पष्ट जांच अक्सर एक कंटेनर के रूप में वस्तु का उपयोग करने और अपवाद को संभालने की कोशिश करने से बेहतर है - जो कोड के साथ सभी प्रकार की समस्याओं को आंशिक या अनावश्यक रूप से चला सकता है।


15
यह जाँचने का एक अच्छा तरीका है कि एक चर चलने योग्य है या नहीं। हालाँकि, यह संभवतः इस प्रश्न के उद्देश्यों के लिए काम नहीं करेगा। सलाह दी जाती है कि एक स्ट्रिंग भी चलने योग्य है और शायद एक झूठी सकारात्मक पैदा करेगा।
कोरी ओ।

एक setवस्तु भी एक चलने योग्य है, जिसका अर्थ है कि जब आप निश्चित रूप से इससे तत्वों को पॉप कर सकते हैं, लेकिन यह एक निश्चित आदेश की गारंटी नहीं देता है, जो कि कुछ एल्गोरिदम के लिए एक बहुत ही खतरनाक चीज है। मामलों में जब तत्वों का क्रम मायने रखता है, तो इस स्निपेट का उपयोग करने वाला एक एल्गोरिथ्म संभवतः अलग-अलग रन पर अलग-अलग परिणाम उत्पन्न कर सकता है!
कू


12

कैसे के बारे में hasattr(a, "__iter__"):?

यह बताता है कि क्या लौटी हुई वस्तु जनरेटर के रूप में पुनरावृत्त हो सकती है। डिफ़ॉल्ट रूप से, टुपल्स और सूचियां, लेकिन स्ट्रिंग प्रकार नहीं हो सकते।


मुझे यह वास्तव में उपयोगी लगा।
जावदबा

8
इसके अलावा स्ट्रिंग्स के लिए ट्रू परिणाम (कम से कम पायथन 3 पर)।
स्ज़िएबर्थअडम

2
यह गलत उत्तर है। चूंकि टाइप 'str' में ' iter ' पद्धति भी है। @SzieberthAdam सही था। प्रकार 'सेट' भी चलने योग्य है, लेकिन क्रमबद्ध नहीं है।
PADYMKO

इसके अलावा dicts है __iter__
Thet

यदि आप जारी रखते हैं, तो किसी भी प्रकार का रिवाज किसी भी __iter__कारण से हो सकता है ...
अलेक्जेंडर इरबिस

10

अजगर 2.8 type(list) is listरिटर्न पर false
मैं इस भयानक तरीके से तुलना करने का सुझाव दूंगा:

if type(a) == type([]) :
  print "variable a is a list"

(कम से कम मेरे सिस्टम पर, मैक ओएस एक्स योसेमाइट पर एनाकोंडा का उपयोग करके)


1
क्या प्रकार (ए) सूची भी झूठी का मूल्यांकन करती है?
दिमित्री सिन्तसोव

4
क्या आप अजगर 2.7.8 मतलब है? python.org/dev/peps/pep-0404/#official-pronouncement
कार्ल

नमस्कार, मैं उत्सुक हूं: आप अपने उदाहरण को "भयानक" क्यों मानते हैं?
सेठ कॉननेल

type(list) is listFalseक्योंकि रिटर्न type(list)है type, नहीं listtype(list()) is listया किसी सूची के किसी अन्य उदाहरण के साथ वापस आ जाएगा True
माइकल ग्रीन

8

पाइथन "डक टाइपिंग" का उपयोग करता है, अर्थात यदि चर चर बतख की तरह है, तो उसे बतख होना चाहिए। आपके मामले में, आप शायद इसे पुनरावृत्त करना चाहते हैं, या आप एक निश्चित सूचकांक पर आइटम का उपयोग करना चाहते हैं। आपको बस यह करना चाहिए: अर्थात किसी ब्लॉक में for var:या उसके var[idx]अंदर ऑब्जेक्ट का उपयोग करें try, और यदि आपको कोई अपवाद मिलता है तो यह बतख नहीं था ...


7
इसके साथ समस्या यह है कि अगर varएक स्ट्रिंग पुनरावृत्ति होती है तो संभवतः अप्रत्याशित परिणाम के साथ होगी।
ब्रायन एम। हंट

ब्रायन एम। हंट द्वारा बताए गए तथ्य के बावजूद, अनुमति के बजाय माफी मांगने के मामले में, उनका काफी पाइथोनिक समाधान है।
Géza Török


3

यदि आपको केवल यह जानने की आवश्यकता है कि क्या आप foo[123]चर के साथ अंकन का उपयोग कर सकते हैं , तो आप एक __getitem__विशेषता के अस्तित्व की जांच कर सकते हैं (जो कि जब आप सूचकांक द्वारा एक्सेस करते हैं तो अजगर कॉल करता है)hasattr(foo, '__getitem__')


2

यदि आप वास्तव में फ़ंक्शन तर्क के रूप में किसी भी चीज़ को संभालना चाहते हैं, तो अधिक जटिल परीक्षण होना चाहिए।

type(a) != type('') and hasattr(a, "__iter__")

हालांकि, आमतौर पर यह केवल यह बताने के लिए पर्याप्त है कि कोई फ़ंक्शन पुनरावृत्ति की उम्मीद करता है और फिर केवल जाँच करता है type(a) != type('')

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


2

यह पता लगाने का एक और आसान तरीका है कि क्या एक चर या तो सूची या टपल है या आम तौर पर चर प्रकार की जाँच करें:

    def islist(obj):

        if ("list" in str(type(obj)) ): return True

        else : return False

1

सिद्धांत रूप में, मैं उपरोक्त इग्नासियो से सहमत हूं, लेकिन आप यह जांचने के लिए भी टाइप का उपयोग कर सकते हैं कि क्या कुछ टपल या सूची है।

>>> a = (1,)
>>> type(a)
(type 'tuple')
>>> a = [1]
>>> type(a)
(type 'list')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.