पायथन कोई तुलना नहीं: क्या मुझे "=" या = का उपयोग करना चाहिए?


213

जब मैं तुलना करता हूं तो मेरा संपादक मुझे चेतावनी देता है my_var == None, लेकिन जब मैं उपयोग करता हूं तो कोई चेतावनी नहीं my_var is None

मैंने पायथन शेल में एक परीक्षण किया और निर्धारित किया कि दोनों वैध वाक्यविन्यास हैं, लेकिन मेरा संपादक यह कहना चाहता है कि my_var is Noneइसे पसंद किया जाता है।

क्या यह मामला है, और यदि हां, तो क्यों?


7
PEP 8 कहीं कहता है कि आपको सिंगलटन के प्रयोग की तुलना करनी चाहिए is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatility

2
वह पोस्टर पायथन 3 के बारे में बात कर रहा है, और मेरा सवाल अजगर 2.x के बारे में है। मुझे यकीन नहीं है कि यह दोनों के वारंट के लिए एक बड़ा पर्याप्त अंतर है लेकिन मैंने इस सवाल को संपादित किया कि सिर्फ मामले में ही शामिल किया जाए।
क्ले वार्डेल

2
मुझे नहीं लगता कि यह प्रश्न वास्तव में एक डुप्लिकेट है। अन्य के बारे में == बनाम सामान्य रूप से होता है, यह विशेष रूप से कोई भी नहीं है।
IJ कैनेडी

जवाबों:


254

सारांश:

का प्रयोग करें isजब आप एक वस्तु के खिलाफ जाँच करना चाहते पहचान (अगर देखने के लिए जाँच जैसे varहै None)। ==जब आप समानता की जांच करना चाहते हैं (उदाहरण के लिए) का उपयोग करेंvar के बराबर 3?)।

स्पष्टीकरण:

आपके पास कस्टम कक्षाएं हो सकती हैं जहां my_var == Noneवापस आ जाएगीTrue

उदाहरण के लिए:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isवस्तु पहचान के लिए जाँच । केवल 1 ऑब्जेक्ट है None, इसलिए जब आप ऐसा करते हैं my_var is None, तो आप जाँच रहे हैं कि क्या वे वास्तव में एक ही ऑब्जेक्ट हैं (न केवल समतुल्य हैं वस्तुएं)

दूसरे शब्दों में, ==समतुल्यता के लिए एक जाँच है (जो वस्तु से वस्तु पर परिभाषित की गई है) जबकि isवस्तु पहचान के लिए जाँच:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
कब is Noneसे अलग है == None?
ब्लेंडर

11
@ ब्लेंडर उल्लेखित मामले में। __eq__किसी भी तरह से परिभाषित किया जा सकता है, लेकिन व्यवहार को isइतनी आसानी से नहीं बदला जा सकता है।
लेव लेवित्स्की

5
@LevLevitsky: Mython के उदाहरणों में से एक था "प्रोटोकॉल का विस्तार करना ताकि किसी भी ऑपरेटर को ओवरलोड किया जा सके, यहां तक ​​कि is"। सूचियों पर एक टिप्पणी के बाद, उन्होंने उसे बदल दिया, "... यहां तक ​​कि is(लेकिन केवल यदि आप पागल हैं)।"
abarnert

1
+1, लेकिन यह और भी बेहतर होगा यदि इस उत्तर में PEP 8 संदर्भ शामिल हो जो कि अन्य करते हैं (साथ ही यह भी बताते हैं कि PEP 8 के पीछे का निर्णय क्यों समझ में आता है, जो यह पहले से ही करता है)।
abarnert

3
@abarnert - मुझे यह भी पता नहीं था कि PEP 8 ने यहाँ एक सिफारिश की है। मुद्दा यह है कि वे अलग-अलग ऑपरेटर हैं जो अलग-अलग काम करते हैं। ऐसे मामले हो सकता है object == Noneवास्तव में है सही मुहावरा (हालांकि मैं अपने सिर के ऊपर से किसी भी नहीं सोच सकते हैं)। आपको बस यह जानना होगा कि आप क्या कर रहे हैं।
एमजिल्सन

127

isआम तौर पर तब पसंद किया जाता है जब मनमानी वस्तुओं की तुलना सिंगलटन से की जाती है Noneक्योंकि यह तेज़ और अधिक अनुमानित है।isहमेशा ऑब्जेक्ट आइडेंटिटी से तुलना करता है, जबकि क्या ==करेगा , यह सही प्रकार के ऑपरेंड्स और यहां तक ​​कि उनके ऑर्डरिंग पर भी निर्भर करता है।

इस अनुशंसा के द्वारा समर्थित है पीईपी 8 , जो स्पष्ट रूप से कहा कि "कोई नहीं की तरह एकमात्र तुलना हमेशा से किया जाना चाहिए isया is notनहीं, कभी नहीं समानता ऑपरेटरों।"


6
इसे पोस्ट करने के लिए धन्यवाद; स्वीकृत उत्तर कुछ रोचक बाते बताता है, लेकिन आपका सवाल सीधे तौर पर कुछ ज्यादा ही जवाब देता है।
ल्यूक डेविस

यह अनिवार्य रूप से कार्यान्वयन विस्तार पर निर्भर करने के लिए अजीब लगता है। मुझे इस बात की परवाह क्यों करनी चाहिए कि NoType के कितने उदाहरण हैं?
बॉलपॉइंटबैन

@ बॉलपॉइंटबैन क्योंकि यह एक कार्यान्वयन विवरण नहीं है - Noneवैश्विक स्थिर के तहत केवल एक ही वस्तु है None। यदि कुछ भी है, तो NoneTypeएक कार्यान्वयन विवरण है क्योंकि Noneसिंगलटन के पास कुछ प्रकार होना चाहिए । (तथ्य यह है कि आप इस प्रकार के उदाहरण नहीं बना सकते हैं यह एक अच्छा संकेत है कि इसका एक उदाहरण सिंगलटन होना है।)
user4815162342

@BallpointBen मुझे लगता है कि मुख्य बिंदु यह है कि पायथन वस्तु पहचान की एक मजबूत अवधारणा रखता है। यदि आप यह जांचना चाहते हैं कि कोई वस्तु सभी साधनों के बराबर है या नहीं । यदि आप जांचना चाहते हैं कि कोई वस्तु है , तो उपयोग करें । पीईपी 8 सिफारिश (और इस जवाब का) की बात यह है कि अधिकांश लोग बाद को तब चाहते हैं जब वे किसी के लिए भी जांच करना चाहते हैं, और यह तेजी से और स्पष्ट होने के लिए भी होता है। Noneobj == None Noneobj is None
user4815162342

Noneकैश्ड वस्तुओं की तरह अलग है 0और अन्य छोटे पूर्णांक, जहां कैशिंग वास्तव में एक कार्यान्वयन विवरण है। अंतर यह है कि एक पूर्णांक में आंतरिक मूल्य होता है जो इसके गुण देता है और इसकी गणना की जा सकती है। दूसरी ओर, Noneकोई भी राज्य नहीं है, यह केवल इसकी पहचान है जो मायने रखता है और इसे विशेष बनाता है।
user4815162342

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.