2009-04-15 8 views
46

क्या my_var कोई नहीं हो सकता है जब निम्न प्रारूप का उपयोग करने के लिए यह बुरा अभ्यास है?क्या बयानों में स्थिति मूल्यांकन आदेश पर भरोसा करना सुरक्षित है?

if my_var and 'something' in my_var: 
    #do something 

मुद्दा यह है कि 'something' in my_var एक लेखन त्रुटि फेंक देंगे अगर my_var कोई नहीं है।

या मैं इस्तेमाल करना चाहिए:

if my_var: 
    if 'something' in my_var: 
     #do something 

या

try: 
    if 'something' in my_var: 
     #do something 
except TypeError: 
    pass 

सवाल है, इसके बाद के संस्करण की जो अजगर में सबसे अच्छा अभ्यास (यदि हो तो) है अलग तरीके से व्यक्त करने के लिए?

विकल्प स्वागत है!

उत्तर

64

सशर्त (Python reference here) के आदेश पर निर्भर होना सुरक्षित है, विशेष रूप से आपके द्वारा बताई गई समस्या के कारण - शॉर्ट सर्किट मूल्यांकन करने में सक्षम होना बहुत उपयोगी है जो सशर्तों की एक स्ट्रिंग में समस्याएं पैदा कर सकता है।

कोड इस तरह की अधिकांश भाषाओं में खुलेगी:

IF exists(variable) AND variable.doSomething() 
    THEN ... 
+2

जब मुझे दूसरे की तरह कोड दिखाई देता है, तो मुझे लगता है कि कोडर समझ में नहीं आया कि शॉर्ट-सर्किट मूल्यांकन कैसे काम करता है। – Dana

+1

-1: प्रलेखन से कोई उद्धरण नहीं: http://docs.python.org/library/stdtypes.html#boolean-operations-and-or-not –

+0

@cfi: चूंकि मैं उत्तर परिवर्तन के बाद अपना वोट बदल सकता हूं, मैं अस्पष्ट हूं कि समस्या क्या है। –

1

यह पूरी तरह से सुरक्षित है और मैं यह सब समय है।

1

मैं कोशिश/छोड़कर जाऊंगा, लेकिन यह वैरिएबल के बारे में आप जो जानते हैं उस पर निर्भर करता है।

यदि आप उम्मीद कर रहे हैं कि चर अधिकतर समय मौजूद होगा, तो कोशिश/छोड़कर कम संचालन होता है। यदि आप चर के अधिकांश समय होने की उम्मीद कर रहे हैं, तो एक आईएफ कथन कम संचालन होगा।

+0

क्यों (पठनीयता, प्रदर्शन, आदि)? – tgray

+0

मैंने उत्तर –

27

हाँ यह सुरक्षित है, यह है स्पष्ट रूप से और बहुत स्पष्ट रूप से भाषा संदर्भ में परिभाषित किया:

अभिव्यक्ति x and y पहले x का मूल्यांकन करता है; यदि xfalse है, तो इसका मान लौटाया गया है; अन्यथा, y का मूल्यांकन है और परिणामस्वरूप मान वापस कर दिया गया है।

अभिव्यक्ति x or y पहले x का मूल्यांकन करती है; यदि x सत्य है, तो इसका मूल्य लौटाया गया है; अन्यथा, y का मूल्यांकन है और परिणामस्वरूप मान वापस कर दिया गया है।

+1

कम किया अद्यतन: यह "सुरक्षित" नहीं है - यह पूरी तरह से आदेश पर निर्भर होना आवश्यक है। –

1

यह इतना आसान नहीं है।

if(x != null && ! string.isnullorempty(x.Name)) 
{ 
    //do something 
} 

ऊपर अच्छा काम करता है और अपेक्षा के अनुरूप मूल्यांकन किया जाता है: एक सी # दोस्त के रूप में मैं बहुत की तरह कुछ कर रही करने के लिए इस्तेमाल कर रहा हूँ। हालांकि वीबी.Net में निम्नलिखित परिणाम उत्पन्न नहीं होंगे:

If Not x Is Nothing **And** Not String.IsNullOrEmpty(x.Name) Then 

    'do something 

End If 

उपर्युक्त अपवाद उत्पन्न करेगा।सही वाक्यविन्यास

If Not x Is Nothing **AndAlso** Not String.IsNullOrEmpty(x.Name) Then 

    'do something 

End If 

बहुत सूक्ष्म अंतर नोट करें। इससे मुझे लगभग 10 मिनट (रास्ता बहुत लंबा) भ्रमित कर दिया गया था और यही वजह है कि सी # (और अन्य) दोस्तों को अन्य भाषाओं में कोडिंग करते समय बहुत सावधान रहना चाहिए।

2

मैं यहाँ एक छोटे से पंडिताऊ जा रहा है हो सकता है लेकिन मैं कहूंगा कि सर्वश्रेष्ठ उत्तर

if my_var is not None and 'something' in my_var: 
    #do something 

अंतर True या False करने के लिए my_var की अंतर्निहित रूपांतरण None के लिए स्पष्ट की जांच के बजाय जा रहा है।

जब मैं अपने मामले में यकीन है कि अंतर महत्वपूर्ण नहीं है, और अधिक सामान्य मामले में यह काफी संभव होगा है के लिए चर नहीं करने के लिए None हो, लेकिन अभी भी 0 के एक पूर्णांक मूल्य उदाहरण के लिए, False का मूल्यांकन या एक खाली सूची

तो अधिकांश पोस्टर्स के दावों के विपरीत यह सुरक्षित है, मैं कहूंगा कि जब तक आप स्पष्ट हैं तब तक यह सुरक्षित है। आप आश्वस्त नहीं कर रहे हैं तो यह बहुत काल्पनिक वर्ग पर विचार करें:

class Contrived(object): 
    def __contains__(self, s): 
     return True 
    def __nonzero__(self): 
     return False 

my_var = Contrived() 
if 'something' in my_var: 
    print "Yes the condition is true" 
if my_var and 'something' in my_var: 
    print "But this statement won't get reached." 
if my_var is not None and 'something' in my_var: 
    print "Whereas this one will." 

हाँ मुझे पता है कि एक यथार्थवादी उदाहरण नहीं है, लेकिन बदलाव के असली कोड में होता है, खासकर जब None एक डिफ़ॉल्ट समारोह तर्क इंगित करने के लिए प्रयोग किया जाता है।

+0

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

+1

हां, यह एक प्रत्याशित उदाहरण है, लेकिन मेरा मुख्य बिंदु यह है कि 'अगर var'' कहने की बुरी आदत में जाना आसान है, जब आप वास्तव में 'अगर var कोई नहीं है' 'कहता है। एक बार जब आप उस आदत में आ जाएंगे तो यह आपको आसानी से डिफॉल्ट तर्कों के साथ आसानी से काट सकता है। –

+0

मुझे लगता है कि यह स्पष्ट है कि ओपी का इरादा 'अगर var' कहना था और यही वह है जो उसने किया था। – SilentGhost

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