2013-04-05 8 views
8

मैं कुछ नहीं बल्कि crufty कोड पुनर्रचना किया गया है और निम्नलिखित बल्कि अजीब निर्माण भर में आया था:अगर (foo या पट्टी या baz) है कोई नहीं:

#!/usr/bin/env python2.7 
# ... 
if (opts.foo or opts.bar or opts.baz) is None: 
    # (actual option names changed to protect the guilty) 
    sys.stderr.write("Some error messages that these are required arguments") 

... और मैं सोच रही थी कि अगर यह कभी होता किसी भी कल्पनाशील भावना बनाओ।

मैं की तरह कुछ करने के लिए इसे बदल दिया है:

#!/usr/bin/env python2.7 
if None in (opts.foo, opts.bar, opts.baz): 
    # ... 

मैं था एक दुभाषिया ऊपर आग और वास्तव में पहले निर्माण की कोशिश ... यह केवल यदि मान सभी झूठे हैं काम करने के लिए लगता है और के अंतिम ये झूठे मूल्य कोई नहीं है। (दूसरे शब्दों में सीपीथन का कार्यान्वयन या अभिव्यक्तियों की श्रृंखला से पहला सच्चा या अंतिम झूठा मान वापस करने लगता है)।

मैं अब भी संदेह है कि उचित कोड का उपयोग करना चाहिए या तो किसी भी() या सभी() बनाया-इन जो 2.5 जोड़ा गया था (प्रश्न में कोड पहले से ही 2.7 की आवश्यकता है)। मुझे अभी तक यकीन नहीं है कि पसंदीदा/इच्छित अर्थशास्त्र कौन सा है क्योंकि मैं अभी इस परियोजना से शुरू कर रहा हूं।

तो क्या कोई ऐसा मामला है जहां यह मूल कोड समझ में आएगा?

+0

कि भयानक है। सावधान रहें कि आप इसे ठीक करके एक नया बग पेश नहीं करते हैं :) –

उत्तर

5

शॉर्ट सर्किटिंग व्यवहार foo or bar or baz का कारण बनता है जो तीन मूल्यों में से पहला है जो बुलियन-सत्य है, या अंतिम मूल्य यदि सभी बूलियन-झूठे हैं। तो इसका मूल रूप से अर्थ है "यदि सभी झूठे हैं और अंतिम कोई नहीं है"।

आपका परिवर्तित संस्करण थोड़ा अलग है। if None in (opts.foo, opts.bar, opts.baz), उदाहरण के लिए, if ब्लॉक दर्ज करें यदि opts.foo कोई नहीं है और अन्य दो 1 हैं, जबकि मूल संस्करण नहीं होगा (क्योंकि None or 1 or 1 1 का मूल्यांकन करेगा, जो कोई नहीं है)। आपका संस्करण if जब किसी भी तीन की कोई नहीं, क्या अन्य दो हैं, जबकि मूल संस्करण if में प्रवेश करेंगे की परवाह किए बिना केवल तभी पिछले कोई नहीं और है अन्य दो किसी भी boolean- हैं में प्रवेश करेंगे झूठे मूल्य

आप जो दो संस्करण चाहते हैं, इस पर निर्भर करता है कि शेष कोड कैसे संरचित किया जाता है और विकल्पों में क्या मूल्य हो सकता है (विशेष रूप से, चाहे वे किसी भी अन्य के अलावा बूलियन-झूठे मूल्य हो, जैसे कि False या 0 या एक खाली स्ट्रिंग)। सहजता से आपका संस्करण अधिक उचित प्रतीत होता है, लेकिन यदि कोड में इस तरह की अनोखी चाल है, तो आप कभी नहीं जानते कि किन कोने के मामले सामने आ सकते हैं।

5

यह इस तरह से व्यवहार कर रहा है क्योंकि or एक शॉर्ट-सर्किट ऑपरेटर है, विवरण docs में हैं।

if opts.baz is None 

हम उस कोड की उम्मीद किस लेखक लगता है कि हो सकता है: इस प्रकार अपने पहले if बयान के बराबर है। मुझे लगता है कि, जैसा आपने बताया है, उन्होंने not all([opts.foo, opts.bar, opts.baz]) का उपयोग करने के बारे में सोचा था।

+1

अपने प्रश्न का उत्तर अधिक विशेष रूप से देने के लिए: ऐसा लगता है कि कोड त्रुटि में है और मैं ऐसे मामले के बारे में नहीं सोच सकता जहां यह समझ में आएगा। – Anorov

+1

अगर वहां कोई "है" ऑपरेटर नहीं होता तो यह समझ में आता है। लेकिन यह तकनीकी रूप से परीक्षण कर रहा है यदि सभी मूल्य झूठे * और * अंतिम का मूल्यांकन करते हैं, विशेष रूप से, कोई भी सिंगलटन का संदर्भ नहीं है। –

+0

@JimDennis वास्तव में – Anorov

0

मैं

if any(i is None for i in (opts.foo, opts.bar, opts.baz)) 

पसंद करते हैं के रूप में यह वास्तव में इरादा लक्ष्य को व्यक्त करता होगा।

OTOH,

not all([opts.foo, opts.bar, opts.baz]) 

असत्यता के लिए जाँच करता है, None के लिए नहीं।

मूल कोड समझ में नहीं आता है; ऐसा लगता है कि वे किसी के द्वारा अनजान हैं कि वे क्या कर रहे हैं।

0

के अपने कोड के दोनों दो की कोशिश करते हैं:

In [20]: foo = True 

In [22]: bar = None 

In [23]: baz = None 

In [24]: foo or bar or baz 
Out[24]: True 

In [25]: (foo or bar or baz) is None 
Out[25]: False 

In [28]: ((foo or bar or baz) is None) == (None in (foo, bar, baz)) 
Out[28]: False 

आप देख सकते हैं आपका रीराइट मूल कोड के रूप में ही नहीं है।

आपका पहली शर्त केवल यह सच है लौटने जब अपने चर के सभी कोई नहीं

In [19]: (None or None or None) is None 
Out[19]: True 

है तो आप के लिए अपना पहला हालत पुनर्लेखन कर सकते हैं:

if foo == bar == bar == None: 
+0

मैंने स्वीकार किया कि अर्थशास्त्र अलग हैं; यहां बिंदु यह अनुमान लगाया गया है कि मूल अर्थशास्त्र के लिए कोई व्यावहारिक मामला सही है या नहीं। मुझे लगता है कि पिछला कोड विभिन्न कोने मामलों में विफल रहा होगा, जो खुशी से, प्रैक्टिस में कभी नहीं देखा गया है। (यह एक आंतरिक कमांड लाइन उपयोगिता का हिस्सा है जिसका उपयोग केवल कुछ ही कर्मचारियों के सदस्यों द्वारा किया गया है)। –

संबंधित मुद्दे