यह इस बात का एक बड़ा उदाहरण है कि __dunder__
तरीकों का सीधे उपयोग क्यों नहीं किया जाना चाहिए क्योंकि वे अपने समकक्ष ऑपरेटरों के लिए अक्सर उपयुक्त प्रतिस्थापन नहीं होते हैं; आपको ==
समानता की तुलना के लिए ऑपरेटर का उपयोग करना चाहिए , या इस विशेष मामले में, जांच करते समय None
, उपयोग करें is
(अधिक जानकारी के लिए उत्तर के नीचे की ओर छोड़ें)।
तुमने कर दिया
None.__eq__('a')
# NotImplemented
NotImplemented
तुलना के प्रकार भिन्न होने के बाद से जो रिटर्न मिलता है । एक और उदाहरण पर विचार करें, जहां इस प्रकार की दो वस्तुओं की तुलना इस प्रकार की जा रही है, जैसे कि 1
और 'a'
। करना (1).__eq__('a')
भी सही नहीं है, और वापस आ जाएगा NotImplemented
। समानता के लिए इन दो मूल्यों की तुलना करने का सही तरीका होगा
1 == 'a'
# False
यहां क्या होता है
- सबसे पहले,
(1).__eq__('a')
कोशिश की जाती है, जो वापस आती है NotImplemented
। यह इंगित करता है कि ऑपरेशन समर्थित नहीं है, इसलिए
'a'.__eq__(1)
कहा जाता है, जो भी लौटाता है NotImplemented
। इसलिए,
- वस्तुओं के साथ ऐसा व्यवहार किया जाता है जैसे कि वे एक जैसी न हों, और
False
वापस आ जाएं।
यह कैसे होता है, यह बताने के लिए कुछ कस्टम कक्षाओं का उपयोग करके एक अच्छा सा MCVE दिया गया है:
class A:
def __eq__(self, other):
print('A.__eq__')
return NotImplemented
class B:
def __eq__(self, other):
print('B.__eq__')
return NotImplemented
class C:
def __eq__(self, other):
print('C.__eq__')
return True
a = A()
b = B()
c = C()
print(a == b)
# A.__eq__
# B.__eq__
# False
print(a == c)
# A.__eq__
# C.__eq__
# True
print(c == a)
# C.__eq__
# True
बेशक, यह स्पष्ट नहीं करता है कि ऑपरेशन सही क्यों है। ऐसा इसलिए है क्योंकि NotImplemented
वास्तव में एक सत्य मूल्य है:
bool(None.__eq__("a"))
# True
के समान,
bool(NotImplemented)
# True
सत्य और असत्य माना जाने वाले मूल्यों के बारे में अधिक जानकारी के लिए, सत्य मान परीक्षण पर डॉक्स अनुभाग और साथ ही इस उत्तर को देखें । यहां यह ध्यान देने योग्य है कि है NotImplemented
truthy है, लेकिन यह किया गया है एक अलग कहानी वर्ग एक परिभाषित किया था होगा __bool__
या __len__
विधि कि लौट आए False
या 0
क्रमशः।
यदि आप ==
ऑपरेटर के कार्यात्मक समकक्ष चाहते हैं , तो उपयोग करें operator.eq
:
import operator
operator.eq(1, 'a')
# False
हालाँकि, जैसा कि पहले उल्लेख किया गया है, इस विशिष्ट परिदृश्य के लिए , जहाँ आप None
उपयोग कर रहे हैं is
:
var = 'a'
var is None
# False
var2 = None
var2 is None
# True
इसके समतुल्य कार्यात्मक उपयोग कर रहा है operator.is_
:
operator.is_(var2, None)
# True
None
एक विशेष वस्तु है, और किसी भी समय स्मृति में केवल 1 संस्करण मौजूद है। IOW, यह NoneType
वर्ग का एकमात्र सिंगलटन है (लेकिन एक ही वस्तु में किसी भी संख्या में संदर्भ हो सकते हैं)। PEP8 दिशा निर्देशों इस स्पष्ट हो जाता है:
None
हमेशा की तरह एकल ऑपरेटरों के साथ तुलना की जानी चाहिए is
या
is not
कभी नहीं, समानता ऑपरेटरों।
सारांश में, जैसे एकल के लिए None
, के साथ एक संदर्भ जांच is
अधिक उपयुक्त है, हालांकि दोनों ==
और is
बस ठीक काम करेगा।