2011-12-19 7 views
14
>>> False in [0] 
True 
>>> type(False) == type(0) 
False 

कारण मैं इस पर ठोकर खाई:पायथन "इन" प्रकार की जांच नहीं करता है?

मेरी यूनिट-परीक्षण के लिए मैं अपने प्रकार के लिए वैध और अवैध उदाहरण मान सूचियां बनाई हैं। ('मेरे प्रकार' के साथ मेरा मतलब है, वे पाइथन प्रकारों के बराबर 100% नहीं हैं) इसलिए मैं सभी मूल्यों की सूची को पुन: सक्रिय करना चाहता हूं और उम्मीद करता हूं कि वे मेरे मान्य मानों में हैं, और दूसरी तरफ, अगर वे नहीं हैं तो असफल हो जाएं। कि इतनी अच्छी तरह से अब काम नहीं करता:

>>> valid_values = [-1, 0, 1, 2, 3] 
>>> invalid_values = [True, False, "foo"] 
>>> for value in valid_values + invalid_values: 
...  if value in valid_values: 
...   print 'valid value:', value 
... 
valid value: -1 
valid value: 0 
valid value: 1 
valid value: 2 
valid value: 3 
valid value: True 
valid value: False 
पाठ्यक्रम मैं पिछले दो 'वैध' मूल्यों से असहमत के

क्या इसका मतलब है कि मुझे वास्तव में अपने वैध_वृत्तियों के माध्यम से पुन: प्रयास करना होगा और प्रकार की तुलना करना होगा?

+0

+1 हम्म, मैंने कभी भी उस पायथन की 'इन' प्रकार की जांच नहीं की है। बहुत ही रोचक । । । – OnesimusUnbound

+0

@ बेनजम्स, हम्म, मुझे आश्चर्य है कि यह पाइथन में बतख टाइपिंग को कैसे तोड़ देगा? – OnesimusUnbound

उत्तर

4

के रूप में दूसरों के लिए लिखा है, "में" कोड क्या नहीं करता है आप इसे करना चाहते हैं। आपको कुछ और चाहिए

तुम सच में एक प्रकार की जांच चाहते हैं (जहां चेक ठीक उसी प्रकार के लिए है) तो आप सूची में प्रकार शामिल कर सकते हैं:

>>> valid_values = [(int, i) for i in [-1, 0, 1, 2, 3]] 
>>> invalid_values = [True, False, "foo"] 
>>> for value in [v[1] for v in valid_values] + invalid_values: 
... if (type(value), value) in valid_values: 
...  print value, "is valid" 
... else: 
...  print value, "is invalid" 
... 
-1 is valid 
0 is valid 
1 is valid 
2 is valid 
3 is valid 
True is invalid 
False is invalid 
foo is invalid 
>>> 

उपप्रकार हैंडलिंग में थोड़ा और अधिक मुश्किल है, और निर्भर करेगा आप क्या करना चाहते हैं

+0

मैंने अतिरिक्त लूप को रोकने के लिए आपके समाधान का उपयोग किया। लेकिन मैंने इसे बदल दिया: valid_values ​​= [(टाइप (v), v) v के लिए [-1, 0, 1, 2, 3]] –

15

समस्या गायब प्रकार की जांच नहीं है, लेकिन क्योंकि पाइथन bool में int का उप-वर्ग है। इस प्रयास करें:

>>> False == 0 
True 
>>> isinstance(False, int) 
True 
+0

मैं झूठी == 0 के बारे में शिकायत नहीं करता, लेकिन केवल इस तथ्य के बारे में कि "इन" इस प्रकार की जांच नहीं करेगा। –

+6

'इन' रिटर्न सही है अगर अनुक्रम में एक आइटम अनुरोधित ऑब्जेक्ट के बराबर है। तो आपकी समस्या 'इन' ऑपरेटर नहीं है, लेकिन '==' ऑपरेटर है। – Constantinius

+0

मैं सिर्फ वहां पहचान के लिए एक जांच करना चाहता हूं। क्या लूप का उपयोग किए बिना ऐसा करने का कोई तरीका है? –

6

documentation के अनुसार, __contains__ संग्रह से अधिक पुनरावृत्ति और == द्वारा तत्वों का परीक्षण किया जाता है। इसलिए वास्तविक समस्या इस तथ्य के कारण होती है, कि False == 0True है।

+0

पैडेंटिक के लिए ... यह पहले '' __contains __ (स्वयं, चीज़) 'विधि के लिए जांचता है, * फिर * ऑब्जेक्ट पर पुनरावृत्त करने के लिए वापस आ जाता है। एक वास्तविक 'सूची' के लिए, '' __contains__'' है, इस प्रकार फॉलबैक। –

+0

@GreggLind आप बिल्कुल सही हैं।हालांकि, मुझे "इन" की बेहतर परिभाषा नहीं मिली। कम से कम आश्चर्य के सिद्धांत के अनुरूप होने के लिए, एक अधिभारित '__contains__' विधि को वैसे भी कुछ करना चाहिए। –

+1

मैंने जनरेटर को निकालने का निर्धारण करते समय मुझे यह काट दिया है और/या हमेशा के लिए चलता है। * स्मार्ट * '' __contains__'' लिखकर से बचें। ('itertools.cycle'' जैसी चीजों के बारे में सोचें) –

3

True == 1 और False == 0 दोनों के बीच अंतर करना मुश्किल है।

एक संभावित लेकिन बदसूरत दृष्टिकोण (जो भी सभी अजगर कार्यान्वयन में काम करने के लिए, लेकिन CPython में ठीक होना चाहिए इसकी गारंटी नहीं है):

>>> for value in valid_values + invalid_values: 
... if value in valid_values and not any(v is value for v in invalid_values): 
...  print ('valid value:', value) 
... 
valid value: -1 
valid value: 0 
valid value: 1 
valid value: 2 
valid value: 3 
+0

मुझे एक और लूप को रोकने के लिए पसंद आया होगा। चूंकि इस चेक को मेरे अधिकांश परीक्षणों के दौरान अक्सर निष्पादित किया जाएगा। –