क्या पायथन में ==
और बीच में कोई अंतर है is
?
हां, उनमें बहुत महत्वपूर्ण अंतर है।
==
: समानता की जाँच करें - शब्दार्थ यह है कि समतुल्य वस्तुएँ (जो कि समान वस्तु नहीं हैं) समान रूप से परीक्षण करेंगी। जैसा कि प्रलेखन कहता है :
ऑपरेटर <,>, ==,> =, <=, और = दो वस्तुओं के मूल्यों की तुलना करते हैं।
is
: पहचान के लिए जाँच - अर्थ विज्ञान हैं कि वस्तु (के रूप में स्मृति में आयोजित) है वस्तु। फिर, प्रलेखन कहता है :
ऑब्जेक्ट आइडेंटिफ़िकेशन के लिए ऑपरेटर is
और is not
टेस्ट: x is y
सच है अगर और केवल अगर x
और y
एक ही ऑब्जेक्ट हैं। id()
फ़ंक्शन का उपयोग करके ऑब्जेक्ट की पहचान निर्धारित की जाती है। x is not y
उलटा सत्य मूल्य देता है।
इस प्रकार, पहचान की जांच वस्तुओं की आईडी की समानता के लिए जाँच के समान है। अर्थात्,
a is b
के समान है:
id(a) == id(b)
id
बिल्टइन फ़ंक्शन कहाँ है जो एक पूर्णांक देता है जो "एक साथ मौजूदा वस्तुओं के बीच अद्वितीय होने की गारंटी है" (देखें help(id)
) और कहाँ a
और b
किसी भी मनमाना ऑब्जेक्ट हैं।
अन्य उपयोग दिशाएँ
आपको उनकी तुलना उनके शब्दार्थ के लिए करनी चाहिए। is
पहचान ==
की जांच करने और समानता की जांच करने के लिए उपयोग करें ।
तो सामान्य तौर पर, हम उपयोग करते हैं is
पहचान के लिए जांच करते हैं। यह आमतौर पर तब उपयोगी होता है जब हम एक ऐसी वस्तु की जाँच कर रहे होते हैं जिसे केवल एक बार मेमोरी में मौजूद होना चाहिए, जिसे प्रलेखन में "सिंगलटन" कहा जाता है।
is
शामिल मामलों के लिए उपयोग करें :
None
- Enum मान (Enum मॉड्यूल से Enums का उपयोग करते समय)
- आमतौर पर मॉड्यूल
- आमतौर पर कक्षा की वस्तुओं को वर्ग परिभाषाओं के परिणामस्वरूप
- आमतौर पर फ़ंक्शन परिभाषाओं से उत्पन्न होने वाली वस्तुएं
- कुछ और जो केवल एक बार स्मृति में मौजूद होना चाहिए (सभी एकल, आम तौर पर)
- एक विशिष्ट वस्तु जिसे आप पहचान द्वारा चाहते हैं
==
शामिल करने के लिए सामान्य उपयोग के मामले :
- पूर्णांकों सहित संख्याएँ
- तार
- सूचियों
- सेट
- शब्दकोशों
- कस्टम म्यूटेबल ऑब्जेक्ट्स
- अन्य बिलियन अपरिवर्तनीय वस्तुओं, ज्यादातर मामलों में
सामान्य उपयोग का मामला, फिर, के लिए ==
, वह वस्तु है जो आप चाहते हैं कि एक ही वस्तु न हो , इसके बजाय यह एक समतुल्य हो सकता है एक
पीईपी 8 दिशा
पीईपी 8, मानक पुस्तकालय के लिए आधिकारिक पायथन शैली गाइड में निम्नलिखित दो मामलोंis
का भी उल्लेख किया गया है :
None
हमेशा की तरह एकल ऑपरेटरों के साथ तुलना की जानी चाहिए is
या
is not
कभी भी समानता ऑपरेटरों के साथ नहीं होनी चाहिए ।
इसके अलावा, लिखने से सावधान रहें if x
जब आप वास्तव में मतलब रखते हैं if x is not None
- उदाहरण के लिए परीक्षण करते समय कि क्या एक चर या तर्क जो डिफॉल्ट करता है None
वह कुछ अन्य मूल्य पर सेट किया गया था। दूसरे मूल्य में एक प्रकार (जैसे कंटेनर) हो सकता है जो बूलियन संदर्भ में गलत हो सकता है!
पहचान से समानता का हवाला देते हुए
अगर is
सच है, तो समानता आमतौर पर हो सकती है बांझ हो सकती है - तार्किक रूप से, यदि कोई वस्तु स्वयं है, तो उसे स्वयं के बराबर परीक्षण करना चाहिए।
ज्यादातर मामलों में यह तर्क सही है, लेकिन यह __eq__
विशेष पद्धति के कार्यान्वयन पर निर्भर करता है । जैसा कि डॉक्स कहते हैं,
समानता तुलना ( ==
और !=
) के लिए डिफ़ॉल्ट व्यवहार वस्तुओं की पहचान पर आधारित है। इसलिए, समान पहचान वाले उदाहरणों की समानता की तुलना समानता में होती है, और विभिन्न पहचानों वाले उदाहरणों की समानता तुलना में असमानता होती है। इस डिफ़ॉल्ट व्यवहार के लिए एक प्रेरणा यह इच्छा है कि सभी वस्तुओं को प्रतिवर्त होना चाहिए (अर्थात x का अर्थ है x == y)।
और संगति के हितों में, अनुशंसा करता है:
समानता की तुलना प्रतिवर्त होनी चाहिए। दूसरे शब्दों में, समान वस्तुओं की तुलना बराबर होनी चाहिए:
x is y
का तात्पर्य x == y
हम देख सकते हैं कि यह कस्टम ऑब्जेक्ट्स के लिए डिफ़ॉल्ट व्यवहार है:
>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
गर्भनिरोधक भी आम तौर पर सच है - अगर किसी चीज़ के परीक्षण के बराबर नहीं है, तो आप आमतौर पर अनुमान लगा सकते हैं कि वे समान वस्तु नहीं हैं।
चूंकि समानता के लिए परीक्षणों को अनुकूलित किया जा सकता है, इसलिए यह अनुमान हमेशा सभी प्रकारों के लिए सही नहीं होता है।
एक अपवाद
एक उल्लेखनीय अपवाद है nan
- यह हमेशा स्वयं के बराबर नहीं के रूप में परीक्षण करता है:
>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan # !!!!!
False
पहचान के लिए जाँच करना समानता के लिए जाँच करने की तुलना में बहुत तेज़ जाँच हो सकती है (जिसके लिए सदस्यों की पुनरावर्ती जाँच की आवश्यकता हो सकती है)।
लेकिन इसे समानता के लिए प्रतिस्थापित नहीं किया जा सकता है जहाँ आपको एक से अधिक ऑब्जेक्ट समान के रूप में मिल सकते हैं।
ध्यान दें कि सूचियों और टुपल्स की समानता की तुलना यह मान लेगी कि वस्तुओं की पहचान बराबर है (क्योंकि यह एक तेज़ जाँच है)। यह विरोधाभास पैदा कर सकता है यदि तर्क असंगत है - जैसा कि यह है nan
:
>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
एक सावधानी कथा:
प्रश्न is
पूर्णांक की तुलना करने के लिए उपयोग करने का प्रयास कर रहा है । आपको यह नहीं समझना चाहिए कि पूर्णांक का एक उदाहरण उसी उदाहरण के समान है जिसे किसी अन्य संदर्भ द्वारा प्राप्त किया गया है। यह कहानी बताती है कि क्यों।
एक टिप्पणीकार के पास कोड था जो इस तथ्य पर निर्भर करता था कि छोटे पूर्णांक (-5 से 256 समावेशी) समानता के लिए जांचने के बजाय पायथन में एकल हैं।
वाह, यह कुछ कपटी कीड़े पैदा कर सकता है। मेरे पास कुछ कोड थे जो अगर a, b है, जो कि मैं चाहता था के रूप में काम करता था क्योंकि a और b आमतौर पर छोटी संख्या है। बग केवल उत्पादन के छह महीने बाद आज ही हुआ है, क्योंकि ए और बी अंत में काफी बड़े थे जिन्हें कैश नहीं किया गया था। - gwg
इसने विकास में काम किया। यह कुछ unittests पारित हो सकता है।
और इसने उत्पादन में काम किया - जब तक कोड एक पूर्णांक 256 से बड़ा नहीं हो जाता, तब तक यह उत्पादन में विफल रहा।
यह एक उत्पादन विफलता है जिसे कोड समीक्षा या संभवतः एक स्टाइल-चेकर के साथ पकड़ा जा सकता था।
मुझे जोर देने दें: पूर्णांक की तुलना करने के लिए उपयोग न करें is
।
echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo
आउटपुटFalse True False
:।