पायथन में मुझे कैसे परीक्षण करना चाहिए अगर एक चर कोई नहीं, सच्चा या गलत है


147

मेरे पास एक फ़ंक्शन है जो तीन चीजों में से एक को वापस कर सकता है:

  • सफलता ( True)
  • असफलता ( False)
  • त्रुटि पढ़ने / पार्सिंग स्ट्रीम ( None)

मेरा सवाल यह है कि अगर मुझे इसके खिलाफ परीक्षण नहीं करना है Trueया False, मुझे यह कैसे देखना चाहिए कि परिणाम क्या है। नीचे बताया गया है कि वर्तमान में मैं यह कैसे कर रहा हूं:

result = simulate(open("myfile"))
if result == None:
    print "error parsing stream"
elif result == True: # shouldn't do this
    print "result pass"
else:
    print "result fail"

क्या यह वास्तव में == Trueभाग को हटाने के रूप में सरल है या मुझे एक त्रिकोणीय बूल डेटा-प्रकार जोड़ना चाहिए। मैं नहीं चाहता कि simulateफ़ंक्शन अपवाद को फेंक दे, क्योंकि मैं चाहता हूं कि बाहरी कार्यक्रम एक त्रुटि के साथ यह लॉग इन करें और जारी रखें।


तुम गलत सवाल पूछ रहे हो; आपको अपने परिणाम को परिभाषित करने में मदद के लिए पूछना चाहिए ... "असफलता" और "त्रुटि पार्सिंग स्ट्रीम" के बीच आप क्या अंतर महसूस करते हैं, उनका क्या मतलब है, परिणाम क्या हैं, कॉल करने वाले को क्या कार्रवाई करने की संभावना है प्रत्येक मामले में (पास, फेल, पार्स त्रुटि)?
जॉन मैकिन

मैं एक विद्युत शक्ति प्रणाली का अनुकरण कर रहा हूं, अगर लोग अपने घरों में बिजली खो देते हैं तो यह एक विफलता है। अगर मैं सिमुलेशन फाइल नहीं पढ़ सकता हूं तो यह पूरी तरह से अलग तरह की त्रुटि है।
जेम्स ब्रूक्स

2
simulateफ़ंक्शन के अंदर मैं सभी अपवादों को पकड़ता हूं; मुझे ऐसा कुछ भी नहीं चाहिए जो सिम्युलेटर के अंदर होता है ताकि बाकी प्रोग्राम को चालू रखा जा सके (और अगले तत्व को संसाधित किया जा सके)। लेकिन जवाब मुझे अपना मन बदल रहे हैं।
जेम्स ब्रूक्स

1
@ जेम्स ब्रुक्स: सही है। यही कोशिश / प्रसंस्करण को छोड़कर सभी के बारे में है। यदि आपके simulateपास चीजें हैं तो वह पकड़ सकता है और फिर से प्रयास कर सकता है, यह अच्छा है। लेकिन अगर यह "विफल" होता है, तो इसे वापस नहीं आना चाहिए None। इसे केवल उस स्क्रिप्ट के लिए एक अपवाद को उठाना चाहिए जिसने इसे बुलाया था। किसी भी तरह, simulateकिया जाता है। रिटर्निंग Noneएक उचित अपवाद को बढ़ाने के रूप में सहायक नहीं है - या अपवाद को simulateसंभालने के लिए कॉलिंग स्क्रिप्ट में प्रचारित करने की अनुमति देता है ।
S.Lott

1
@ जेम्स, except Exception:इसके बजाय का उपयोग करें । यह सभी "वास्तविक" त्रुटियों को पकड़ता है, साथ में Warningऔर StopIteration। यह अनुमति देता है KeyboardInterruptऔर SystemExitयद्यपि के माध्यम से। यदि आप वास्तव में उन लोगों को पकड़ना चाहते हैं, तो संभवतः किसी अन्य, बाहरी कोशिश / को छोड़कर या किसी अन्य संरचना का उपयोग करना सबसे अच्छा है जो स्पष्ट रूप से आपके इरादे को दस्तावेज करते हैं, क्योंकि वे "त्रुटियां" नहीं हैं। (लेकिन मैंने कहा "लगभग कभी नहीं" ... शायद आपके मामले में आप वास्तव में सब कुछ हड़पना चाहते हैं, और यहां तक ​​कि Ctrl-C या sys.exit()बाहर निकलने से रोकते हैं , आदि)
पीटर हैनसेन

जवाबों:


119

अपवाद से डरो मत! आपका कार्यक्रम बस लॉग इन करना और जारी रखना जितना आसान है:

try:
    result = simulate(open("myfile"))
except SimulationException as sim_exc:
    print "error parsing stream", sim_exc
else:
    if result:
        print "result pass"
    else:
        print "result fail"

# execution continues from here, regardless of exception or not

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


माना। ऊपर स्पष्ट रूप से अधिक लोकप्रिय समाधान की तुलना में बहुत अधिक पायथोनिक (जो सी कोड की तरह बहुत अधिक बदबू आ रही है)।
ब्रैंडन

7
@ ब्रैंड सहमत नहीं। यह कोड ऊपर के समाधान की तुलना में लंबा और बुरा है, कम पठनीय है (या नीचे दिया गया उन्नत संस्करण): अधिक इंडेंटेशन, अधिक भिन्न कथन - अनुमान लगाएं कि उत्तरार्द्ध अधिक लोकप्रिय क्यों है, जैसा कि आप कहते हैं ... ;-) क्यों होने की कोशिश कर रहा है; 'पायथोनिक' यदि अधिक अजीब कोड की ओर जाता है ...?
रॉल्फ बार्टस्ट्रा

अब "त्रुटि पार्सिंग स्ट्रीम" के बजाय ट्रेसबैक प्रिंट करें और आपको मेरा वोट मिला।
CivFan

ठीक है, आपको मेरा वोट वैसे भी मिल गया, लेकिन मेरा मतलब कुछ ऐसा ही था traceback.format_exc() इस SO उत्तर को देखें।
CivFan

11
शीर्षक प्रश्न के उत्तर की तलाश में कई लोग इस पृष्ठ पर आएंगे। हम में से अधिकांश के लिए "अपवाद से डरो मत!" हमारी स्थिति से कोई लेना-देना नहीं है। हमें बस ट्रू, गलत और किसी के लिए परीक्षण करने की आवश्यकता है। जबकि आपका सुझाया गया विकल्प कुछ मामलों के लिए मान्य है, मुझे लगता है कि सवाल का जवाब भी देना सबसे अच्छा है क्योंकि यह पूछा गया था।
विशाललसुपरियोर्मैन

163
if result is None:
    print "error parsing stream"
elif result:
    print "result pass"
else:
    print "result fail"

इसे सरल और स्पष्ट रखें। आप निश्चित रूप से एक शब्दकोश को पूर्व-परिभाषित कर सकते हैं।

messages = {None: 'error', True: 'pass', False: 'fail'}
print messages[result]

यदि आप simulateअधिक रिटर्न कोड शामिल करने के लिए अपने फ़ंक्शन को संशोधित करने की योजना बनाते हैं, तो इस कोड को बनाए रखना थोड़ा मुद्दा बन सकता है।

simulateभी, पार्सिंग त्रुटि पर एक अपवाद बढ़ाई जा सकती है जिस स्थिति में आप या तो इसे यहाँ पकड़ चाहते हैं या यह एक स्तर ऊपर का प्रचार करते हैं और मुद्रण बिट एक पंक्ति है, तो-और कुछ बयान करने के लिए कम किया जाएगा।


1
उत्तरार्द्ध सच या गलत के खिलाफ एक स्पष्ट परीक्षण की तरह है, है ना?
पीटर आइजेंट्रूट

1
बेशक, लेकिन यह जानते हुए कि ये केवल संभव रिटर्न मान हैं, मुझे नहीं लगता कि यह एक समस्या है।
साइलेंटगॉस्ट

और यह थोड़ा तेज होने के साथ
साइलेंटगॉस्ट

a = 'foo' अगर: a 'प्रिंट' a true 'a' वास्तव में TRUE नहीं है, तो यह कोई नहीं है
wesm

17

कभी नहीं, कभी नहीं, कभी नहीं

if something == True:

कभी नहीँ। यह पागल है, क्योंकि आप अनावश्यक रूप से दोहरा रहे हैं कि क्या अनावश्यक रूप से एक अगर-बयान के लिए निरर्थक स्थिति नियम के रूप में निर्दिष्ट है।

इससे भी बदतर, फिर भी, कभी नहीं, कभी नहीं, कभी नहीं

if something == False:

आपके पास है not। इसका इस्तेमाल करने के लिए स्वतंत्र महसूस करें।

अंत में, करना a == Noneअक्षम्य है। करते हैं a is NoneNoneएक विशेष सिंगलटन ऑब्जेक्ट है, केवल एक ही हो सकता है। बस यह देखने के लिए जांचें कि क्या आपके पास वह वस्तु है।


3
समानता के लिए परीक्षण Trueबेमानी नहीं है (हालांकि मैं मानता हूं कि यह समझदार नहीं है)। यह एक __eq__या अन्य विशेष पद्धति कहला सकती है, जो व्यावहारिक रूप से कुछ भी कर सकती है।
स्कॉट ग्रिफ़िथ्स

5
@ स्कॉट ग्रिफ़िथ: अच्छी बात है। यह वास्तव में और गहरा भयानक परिदृश्य है। यदि वास्तव में ऐसा है, तो कार्यक्रम हमारी मूलभूत अपेक्षाओं का उल्लंघन करता है, जिससे यह कुछ ऐसा हो जाता है, जिसे बस हटाने की आवश्यकता होती है और ऐसे काले जादू के बिना खरोंच से फिर से लिखा जाता है।
एस.लॉट S

78
'कभी नहीं, कभी नहीं, कभी नहीं' ...? हालांकि ऐसे मामले हैं जो गैर-बूलियन के लिए की if something == Trueतुलना में एक अलग परिणाम देता है । झूठी उपज देता है जबकि सच का मूल्यांकन करता है; गलत है लेकिन सच है! if somethingsomething2==True2None==Falsenot None
रॉल्फ बारस्ट्रा

9
-1 - यह भ्रामक और पूरी तरह से गलत उत्तर है, क्योंकि @ रॉल्फ बार्थस्ट्रा जो कहता है वह सच है। हालांकि इस मामले में, आप जो कहते हैं उसे लागू किया जा सकता है।
हैलोगूडीबाई

3
-1। somethingरिटर्न के लिए किसी भी गैर-शून्य या गैर-खाली या गैर-शून्य-लंबाई मूल्य के बाद Trueसे bool(something)। उस मामले में, अगर आप केवल जाँच करना चाहते हैं somethingका अपना महत्व होता है Trueयानी bool। फिर आपको if something == TrueIMO करना होगा ।
समर्थ शाह

2

मैं इस बात पर जोर देना चाहूंगा कि, भले ही ऐसी परिस्थितियां हों जहां if expr :पर्याप्त नहीं है क्योंकि कोई यह सुनिश्चित करना चाहता exprहै Trueऔर जो 0/ None/ जो भी हो, उससे अलग नहीं है , उसी कारणis से पसंद किया जाना है == , जिससे बचने के लिए उल्लेख किया गया है== None

यह वास्तव में थोड़ा अधिक कुशल है और, केक पर चेरी, अधिक मानव पठनीय है।

In [1]: %timeit (1 == 1) == True
38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit (1 == 1) is True
33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

1
आप एक बार बेंचमार्क नहीं चला सकते हैं और कह सकते हैं कि एक दूसरे की तुलना में अधिक कुशल है (भले ही यह हो सकता है)। इसे कई बार (10.000) चलाएं यह देखने के लिए कि यह औसत में कैसे व्यवहार करता है। \
user1767754

1

मेरा मानना ​​है कि अपवाद को फेंकना आपकी स्थिति के लिए बेहतर विचार है। एक विकल्प एक ट्यूपल को वापस करने के लिए सिमुलेशन विधि होगी। पहला आइटम स्थिति और दूसरा परिणाम होगा:

result = simulate(open("myfile"))
if not result[0]:
  print "error parsing stream"
else:
  ret= result[1]

1
टपल वापस करना आम तौर पर एक टपल को खोलने के साथ अच्छी तरह से चला जाता है;)
SilentGhost

2
हालाँकि, आपके कोड का बहुत मतलब नहीं है, अगर Falseलौटा दिया गया है, तो यह प्रिंट होगा 'error parsing stream'
साइलेंटगॉस्ट

अनुकरण विधि वापस आनी चाहिए (गलत, "कुछ भी सब पर") या (सच, रिट) जहां रिट या तो गलत है या सच है।
किंजनाककिंस

2
ठीक है, आप अपने तर्क के अनुरूप उत्पादन मूल्यों को फिर से परिभाषित कर रहे हैं, यह स्पष्ट नहीं है w / o एक स्पष्टीकरण
SilentGhost
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.