मैंने इस तरह कोड के कई उदाहरण देखे हैं:
if not someobj:
#do something
लेकिन मैं सोच रहा हूँ कि क्यों नहीं कर रहा:
if someobj == None:
#do something
क्या कोई अंतर है? क्या एक का दूसरे पर फायदा है?
X != None?
मैंने इस तरह कोड के कई उदाहरण देखे हैं:
if not someobj:
#do something
लेकिन मैं सोच रहा हूँ कि क्यों नहीं कर रहा:
if someobj == None:
#do something
क्या कोई अंतर है? क्या एक का दूसरे पर फायदा है?
X != None?
जवाबों:
पहले परीक्षण में, पायथन ऑब्जेक्ट को एक boolमान में बदलने की कोशिश करता है अगर यह पहले से ही एक नहीं है। मोटे तौर पर, हम ऑब्जेक्ट से पूछ रहे हैं: आप सार्थक हैं या नहीं? यह निम्नलिखित एल्गोरिथ्म का उपयोग करके किया जाता है:
यदि ऑब्जेक्ट के पास एक __nonzero__विशेष विधि है (जैसा कि संख्यात्मक बिल्ट-इन intऔर float) करते हैं, तो यह इस विधि को कॉल करता है। इसे या तो एक boolमान वापस करना चाहिए जो फिर सीधे उपयोग किया जाता है, या एक intमूल्य जिसे माना जाता हैFalse शून्य के बराबर है।
अन्यथा, अगर वस्तु एक है __len__विशेष विधि (के रूप में करने कंटेनर का निर्माण इन, list, dict, set, tuple, ...), यह इस प्रणाली को बुलाती है, एक कंटेनर पर विचारFalse अगर यह रिक्त है (लंबाई शून्य है)।
अन्यथा, वस्तु पर विचार Trueतब तक किया जाता है जब तक कि यह Noneकिस स्थिति में है, यह माना जाता है False।
दूसरे परीक्षण में, वस्तु की तुलना समानता के लिए की जाती है None। यहां, हम ऑब्जेक्ट से पूछ रहे हैं, "क्या आप इस अन्य मूल्य के बराबर हैं?" यह निम्नलिखित एल्गोरिथ्म का उपयोग करके किया जाता है:
यदि ऑब्जेक्ट में एक __eq__विधि है, तो इसे कहा जाता है, और रिटर्न वैल्यू को फिर एक boolमूल्य में परिवर्तित किया जाता है और इसका परिणाम निर्धारित करने के लिए उपयोग किया जाता हैif ।
अन्यथा, यदि वस्तु में एक __cmp__विधि है, तो उसे कहा जाता है। इस फ़ंक्शन को intदो ऑब्जेक्ट ( -1यदि self < other, 0यदि self == other, +1यदि self > other) के क्रम को इंगित करते हुए लौटना चाहिए ।
अन्यथा, वस्तु की पहचान के लिए तुलना की जाती है (यानी वे उसी वस्तु के संदर्भ में हैं, जैसा कि isऑपरेटर द्वारा परीक्षण किया जा सकता है )।
isऑपरेटर का उपयोग करके एक और परीक्षण संभव है । हम वस्तु से पूछेंगे, "क्या आप यह विशेष वस्तु हैं?"
आम तौर पर, मैं गैर-संख्यात्मक मानों के साथ पहले परीक्षण का उपयोग करने की सलाह दूंगा, समानता के लिए परीक्षण का उपयोग करने के लिए जब आप एक ही प्रकृति की वस्तुओं की तुलना करना चाहते हैं (दो तार, दो नंबर, ...) और पहचान के लिए केवल जब जांच करने के लिए। प्रहरी मूल्यों का उपयोग करना ( Noneमतलब छूट के लिए सदस्य क्षेत्र के लिए आरंभीकृत नहीं, या उपयोग करते समयgetattr या __getitem__विधि)।
संक्षेप में, हमारे पास है:
>>> class A(object):
... def __repr__(self):
... return 'A()'
... def __nonzero__(self):
... return False
>>> class B(object):
... def __repr__(self):
... return 'B()'
... def __len__(self):
... return 0
>>> class C(object):
... def __repr__(self):
... return 'C()'
... def __cmp__(self, other):
... return 0
>>> class D(object):
... def __repr__(self):
... return 'D()'
... def __eq__(self, other):
... return True
>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
... print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
... (repr(obj), bool(obj), obj == None, obj is None)
'': bool(obj) -> False, obj == None -> False, obj is None -> False
(): bool(obj) -> False, obj == None -> False, obj is None -> False
[]: bool(obj) -> False, obj == None -> False, obj is None -> False
{}: bool(obj) -> False, obj == None -> False, obj is None -> False
0: bool(obj) -> False, obj == None -> False, obj is None -> False
0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
A(): bool(obj) -> False, obj == None -> False, obj is None -> False
B(): bool(obj) -> False, obj == None -> False, obj is None -> False
C(): bool(obj) -> True, obj == None -> True, obj is None -> False
D(): bool(obj) -> True, obj == None -> True, obj is None -> False
None: bool(obj) -> False, obj == None -> True, obj is None -> True
ये वास्तव में दोनों खराब व्यवहार हैं। एक बार, किसी को भी गलत तरीके से और किसी के साथ गलत व्यवहार करना ठीक माना गया था। हालाँकि, पायथन 2.2 के बाद से यह सबसे अच्छी नीति नहीं है।
सबसे पहले, जब आप एक कर if xया if not xपरीक्षण की तरह, अजगर परोक्ष कन्वर्ट करने के लिए है xबूलियन करने के लिए। boolफ़ंक्शन के लिए नियम उन चीजों की एक बेड़ा का वर्णन करते हैं जो झूठी हैं; बाकी सब सच है। यदि x का मान ठीक से शुरू करने के लिए बूलियन नहीं था, तो यह निहित रूपांतरण चीजों को कहने का सबसे स्पष्ट तरीका नहीं है।
पायथन 2.2 से पहले, कोई बूल फ़ंक्शन नहीं था, इसलिए यह और भी कम स्पष्ट था।
दूसरा, आपको वास्तव में परीक्षण नहीं करना चाहिए == None। आपको उपयोग करना चाहिए is Noneऔर is not None।
PEP 8, पायथन कोड के लिए स्टाइल गाइड देखें ।
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators. Also, beware of writing "if x" when you really mean "if x is not None" -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!
कितने एकल हैं? पांच: None, True, False, NotImplementedऔर Ellipsis। चूंकि आप वास्तव में उपयोग करने में असमर्थ हैं NotImplementedया Ellipsis, और आप कभी नहीं कहेंगे if x is True(क्योंकि बस if xबहुत स्पष्ट है), आप कभी भी परीक्षा देंगे None।
क्योंकि Noneकेवल वही चीज नहीं है जो झूठी मानी जाती है।
if not False:
print "False is false."
if not 0:
print "0 is false."
if not []:
print "An empty list is false."
if not ():
print "An empty tuple is false."
if not {}:
print "An empty dict is false."
if not "":
print "An empty string is false."
False, 0, (), [], {}और ""से सभी अलग हैं Noneतो अपने दो कोड स्निपेट कर रहे हैं, नहीं के बराबर।
इसके अलावा, निम्नलिखित पर विचार करें:
>>> False == 0
True
>>> False == ()
False
if object:है न एक समानता की जांच। 0, (), [], None, {}, आदि कर रहे हैं एक दूसरे से सभी अलग, लेकिन वे सभी का मूल्यांकन गलत पर।
यह लघु जादू के पीछे "जादू" है जैसे:
foo = bar and spam or eggs
जिसके लिए आशुलिपि है:
if bar:
foo = spam
else:
foo = eggs
हालाँकि आपको वास्तव में लिखना चाहिए:
foo = spam if bar else egg
पीईपी 8 - पायथन कोड के लिए स्टाइल गाइड का उपयोग करने की सिफारिश की जाती है या नहीं, यदि आप बिना-नेस के परीक्षण कर रहे हैं
- Comparisons to singletons like None should always be done with 'is' or 'is not', never the equality operators.
दूसरी ओर यदि आप नो-नेस से अधिक के लिए परीक्षण कर रहे हैं, तो आपको बूलियन ऑपरेटर का उपयोग करना चाहिए।
अगर आप पूछते हैं
if not spam:
print "Sorry. No SPAM."
स्पैम का __nonzero__ विधि कहा जाता है। पायथन मैनुअल से:
__nonzero__ ( स्व ) सत्य मूल्य परीक्षण को लागू करने के लिए कहा जाता है, और अंतर्निहित ऑपरेशन बूल (); गलत या सही लौटना चाहिए, या उनके पूर्णांक समतुल्य 0 या 1. जब इस विधि को परिभाषित नहीं किया जाता है, तो __len __ () कहा जाता है, यदि यह परिभाषित किया गया है (नीचे देखें)। यदि कोई वर्ग न तो __len __ () और न ही __nonzero __ () को परिभाषित करता है, तो उसके सभी उदाहरण सही माने जाते हैं।
अगर आप पूछते हैं
if spam == None:
print "Sorry. No SPAM here either."
__eq__ की विधि स्पैम तर्क के साथ कॉल हो जाता है कोई नहीं ।
अनुकूलन संभावनाओं की अधिक जानकारी के लिए https://docs.python.org/reference/datamodel.html#basic-customization पर पायथन डॉक्यूमेंटेशन पर एक नज़र डालें
ये दोनों तुलनाएँ अलग-अलग उद्देश्यों की पूर्ति करती हैं। किसी चीज के बूलियन मूल्य के लिए पूर्व जांच, दूसरा बिना मूल्य के पहचान के लिए चेक।
उत्तर है, यह निर्भर करता है"।
मैं पहले उदाहरण का उपयोग करता हूं अगर मैं 0, "", [] और झूठी (सूची से बाहर नहीं निकलने वाली) को इस संदर्भ में किसी के बराबर नहीं मानता हूं।
व्यक्तिगत रूप से, मैंने भाषाओं में एक सुसंगत दृष्टिकोण चुना: मैं if (var)केवल (या समतुल्य) केवल अगर var को बूलियन के रूप में घोषित किया जाता है (या इस तरह परिभाषित किया गया है, C में हमारे पास एक विशिष्ट प्रकार नहीं है)। मैं भी इन चर को एक के साथ उपसर्ग करता हूं b(इसलिए यह bVarवास्तव में होगा ) यह सुनिश्चित करने के लिए कि मैं गलती से यहां दूसरे प्रकार का उपयोग नहीं करूंगा।
मुझे वास्तव में बूलियन के लिए निहित कास्टिंग पसंद नहीं है, यहां तक कि जब कई, जटिल नियम भी कम होते हैं।
बेशक, लोग असहमत होंगे। कुछ आगे बढ़ते हैं, मैं if (bVar == true)अपने काम में जावा कोड में देखता हूं (मेरे स्वाद के लिए बहुत बेमानी!), दूसरों को बहुत अधिक कॉम्पैक्ट सिंटैक्स पसंद है, जा रहा है while (line = getNextLine())(मेरे लिए बहुत अस्पष्ट)।