इस सवाल पर एक टिप्पणी में , मैंने एक बयान देखा जिसका उपयोग करने की सिफारिश की गई थी
result is not None
बनाम
result != None
मैं सोच रहा था कि अंतर क्या है, और एक दूसरे पर सिफारिश क्यों की जा सकती है?
इस सवाल पर एक टिप्पणी में , मैंने एक बयान देखा जिसका उपयोग करने की सिफारिश की गई थी
result is not None
बनाम
result != None
मैं सोच रहा था कि अंतर क्या है, और एक दूसरे पर सिफारिश क्यों की जा सकती है?
जवाबों:
==एक समानता परीक्षण है । यह जाँचता है कि क्या दाहिने हाथ की ओर और बाएं हाथ की तरफ समान वस्तुएं हैं (उनके __eq__या __cmp__तरीकों के अनुसार )।
isएक पहचान परीक्षा है । यह जाँच करता है कि क्या दाहिने हाथ की तरफ और बाएं हाथ की तरफ एक ही वस्तु है। कोई कार्यप्रणाली नहीं की जाती है, ऑब्जेक्ट isऑपरेशन को प्रभावित नहीं कर सकते हैं ।
आप सिंगलटन के लिए is(और is not) का उपयोग करते हैं , जैसे None, जहाँ आप उन वस्तुओं के बारे में परवाह नहीं करते हैं जो होने का नाटक करना चाहते हैं Noneया जहाँ आप उन वस्तुओं की रक्षा करना चाहते हैं जिनके खिलाफ तुलना की जा रही है None।
Noneकुछ तरीके हैं और लगभग कोई विशेषता नहीं है। यदि आपके __eq__परीक्षण से विधि या विशेषता की उम्मीद है, तो यह टूट सकता है। def __eq__( self, other ): return self.size == other.size। उदाहरण के लिए, अगर otherऐसा होता है तो टूट जाएगा None।
isजावा की तरह है ==। अजगर का ==जावा की तरह है .equals()। बेशक यह केवल तभी मदद करता है जब आप जावा को जानते हैं।
isतरह है ===(बहुत बराबर), और इसके विपरीत is notकी तरह है !==(वास्तव में बराबर नहीं)।
is notएक भी ऑपरेटर या यह सिर्फ का परिणाम negating है isकी तरह आंतरिक रूप से not foo is bar?
पहले, मुझे कुछ शर्तों पर जाने दें। यदि आप केवल अपने प्रश्न का उत्तर चाहते हैं, तो "अपने प्रश्न का उत्तर दें" पर स्क्रॉल करें।
वस्तु पहचान : जब आप एक वस्तु बनाते हैं, तो आप इसे एक चर में निर्दिष्ट कर सकते हैं। फिर आप इसे दूसरे चर पर भी असाइन कर सकते हैं। और दुसरी।
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
इस मामले में cancel, closeऔर, dismissसभी एक ही ऑब्जेक्ट को मेमोरी में संदर्भित करते हैं। आपने केवल एक Buttonऑब्जेक्ट बनाया है , और सभी तीन चर इस एक ऑब्जेक्ट को संदर्भित करते हैं। हम कहते हैं कि cancel, closeऔर dismissसभी समान वस्तुओं को संदर्भित करते हैं ; अर्थात्, वे एक ही वस्तु को संदर्भित करते हैं।
वस्तु समानता : जब आप दो वस्तुओं की तुलना करते हैं, तो आप आमतौर पर ध्यान नहीं देते हैं कि यह स्मृति में सटीक समान ऑब्जेक्ट को संदर्भित करता है । वस्तु समानता के साथ, आप दो वस्तुओं की तुलना कैसे करते हैं, इसके लिए आप अपने स्वयं के नियमों को परिभाषित कर सकते हैं। जब आप लिखते हैं if a == b:, आप अनिवार्य रूप से कह रहे हैं if a.__eq__(b):। यह आपको एक __eq__विधि को परिभाषित करने देता है aताकि आप अपने स्वयं के तुलना तर्क का उपयोग कर सकें।
औचित्य: दो वस्तुओं में एक ही डेटा होता है, लेकिन समान नहीं होते हैं। (वे स्मृति में एक ही वस्तु नहीं हैं।) उदाहरण: स्ट्रिंग्स
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
नोट: मैं यहां यूनिकोड स्ट्रिंग्स का उपयोग करता हूं, क्योंकि पायथन काफी स्मार्ट है, जो नियमित स्ट्रिंग्स को फिर से उपयोग किए बिना मेमोरी में बनाता है।
यहाँ, मेरे पास दो यूनिकोड स्ट्रिंग्स हैं, aऔर b। उनके पास समान सामग्री है, लेकिन वे स्मृति में समान वस्तु नहीं हैं। हालांकि, जब हम उनकी तुलना करते हैं, तो हम चाहते हैं कि वे बराबर की तुलना करें। यहाँ क्या हो रहा है कि यूनिकोड ऑब्जेक्ट ने __eq__विधि को लागू किया है।
class unicode(object):
# ...
def __eq__(self, other):
if len(self) != len(other):
return False
for i, j in zip(self, other):
if i != j:
return False
return True
नोट: निश्चित रूप से इस से अधिक कुशलता से लागू __eq__किया unicodeजाता है।
Rationale: दो वस्तुओं के अलग-अलग डेटा होते हैं, लेकिन यदि कुछ प्रमुख डेटा समान हों तो उन्हें एक ही वस्तु माना जाता है। उदाहरण: अधिकांश प्रकार के मॉडल डेटा
>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True
यहाँ, मेरे पास दो डेल मॉनिटर हैं, aऔर b। उनके पास एक ही मेक और मॉडल है। हालाँकि, उनके पास न तो समान डेटा है और न ही मेमोरी में समान ऑब्जेक्ट हैं। हालांकि, जब हम उनकी तुलना करते हैं, तो हम चाहते हैं कि वे बराबर की तुलना करें। यहाँ क्या हो रहा है कि मॉनिटर ऑब्जेक्ट ने __eq__विधि को लागू किया ।
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
तुलना करते समय None, हमेशा उपयोग करें is not। पायथन में कोई भी एकल नहीं है - स्मृति में इसका केवल एक उदाहरण है।
पहचान की तुलना करके , यह बहुत जल्दी प्रदर्शन किया जा सकता है। पायथन यह जाँचता है कि जिस ऑब्जेक्ट का आप उल्लेख कर रहे हैं, उसमें वैसा ही मेमोरी एड्रेस है जैसा कि वैश्विक कोई भी वस्तु नहीं है - दो नंबरों की तुलना में बहुत तेज।
समानता की तुलना करके , पायथन को यह देखना होगा कि आपकी वस्तु में कोई __eq__विधि है या नहीं। यदि ऐसा नहीं होता है, तो यह एक __eq__विधि की तलाश में प्रत्येक सुपरक्लास की जांच करता है । यदि यह एक पाता है, तो पायथन इसे कहता है। यह विशेष रूप से बुरा है यदि __eq__विधि धीमी है और तुरंत वापस नहीं आती है जब यह नोटिस करता है कि दूसरी वस्तु है None।
आपने लागू नहीं किया __eq__? तब पायथन संभवत: इस __eq__पद्धति को खोजेगा objectऔर इसके बजाय इसका उपयोग करेगा - जो कि वैसे भी वस्तु पहचान के लिए जांच करता है।
पायथन में अधिकांश अन्य चीजों की तुलना करते समय, आप उपयोग कर रहे होंगे !=।
निम्नलिखित को धयान मे रखते हुए:
class Bad(object):
def __eq__(self, other):
return True
c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
Noneएक सिंगलटन है, इसलिए पहचान की तुलना हमेशा काम करेगी, जबकि एक वस्तु समानता तुलना के माध्यम से नकली हो सकती है .__eq__()।
None, लेकिन Noneअन्य प्रकार के खिलाफ समानता को लागू करने के दुष्प्रभाव के रूप में गलत व्यवहार हो सकता है। यह इतना सुरक्षा निहितार्थ नहीं है क्योंकि यह सिर्फ शुद्धता निहितार्थ है।
>>> () है () सच >>> 1 1 है सच >>> (1,) == (1,) सच >>> (1,) है (1,) असत्य >>> ए = (1) >>> बी = ए >>> ए बी है सच
कुछ ऑब्जेक्ट एकल हैं, और इस तरह isउनके साथ समतुल्य है ==। ज्यादातर नहीं हैं।
()और 1स्वाभाविक रूप से एकल नहीं हैं।
-NSMALLNEGINTS <= n <= NSMALLPOSINTS) और खाली ट्यूपल एकल हैं । वास्तव में यह न तो प्रलेखित है और न ही इसकी गारंटी है, लेकिन यह बदलने की संभावना नहीं है।