2013-04-20 12 views
16

सभी को एक अपवाद कैसे संभालें?सभी को एक अपवाद को संभालना

try: 
    ... 
except SomeException: 
    raise 
except: 
    ... 

raise किसी भी अभिव्यक्ति के बिना के बाद कहीं भी होगी सरल उठाने पिछले फेंका अपवाद (भले ही संभाला गया है!):

try: 
    something 
except NoChildException: 
    raise NoChildException 
except: 
    pass 
+4

सरल उत्तर: नहीं। सभी अपवादों को पकड़ने के लिए यह वास्तव में खराब प्रथा है, क्योंकि आप उन लोगों को पकड़ने के लिए प्रवृत्त होंगे जिनके बारे में आप मतलब नहीं थे, त्रुटियों को अस्पष्ट करना। ऐसी चीज करने के लिए केवल वैध मामलों की एक छोटी संख्या है। –

+2

आपने अपने खुद के प्रश्न का उत्तर दिया है। हमें बताएं कि आप अपने पास से असंतुष्ट क्यों हैं। –

+0

@ रोब काफी नहीं, उसका उदाहरण एक * नया * अपवाद बना देगा, पुराने को फिर से नहीं उठाएगा। –

उत्तर

24

जवाब बस raise करना है। यह मोटे तौर पर के बराबर है: आपको लगता है एक और अपवाद कैच ब्लॉक (स्पष्ट रूप से इस मामले में असंभव) में फेंक दिया जा सकता है, तो

except SomeException as e: 
    raise e 

, यदि आप बाद प्रारूप का उपयोग सुनिश्चित करने के लिए आप सही अपवाद फिर से उठाना चाहिए।

हालांकि, मेरी टिप्पणी में बताया गया है:

सरल जवाब: नहीं। अपवादों को पकड़ने के लिए यह वास्तव में खराब अभ्यास है, क्योंकि आप उन लोगों को पकड़ने के लिए प्रवृत्त होंगे जिनके लिए आपका मतलब नहीं था, त्रुटियों को अस्पष्ट करना। ऐसी चीज करने के लिए केवल वैध मामलों की एक छोटी संख्या है।

बस उन त्रुटियों को पकड़ें जो आपको लगता है कि आपका कोड फेंक सकता है, और आप जानते हैं कि कैसे संभालना है, और किसी अन्य को छोड़ दें। यदि कुछ और होता है, तो आपका प्रोग्राम बाहर निकल जाएगा - जो है जो आप चाहते हैं, क्योंकि आप देख सकते हैं कि यह क्यों हुआ और इसे सही तरीके से संभाल लें।

+2

+1 "इसे मत करें" – Aya

+0

मैं सहमत हूं। लेकिन मुझे यह मिलता है: विफल: आपकी Patient.update विधि को ज़ीरोडिविजन त्रुटि के अपवाद को पकड़ा गया जब यह नहीं होना चाहिए। आपको अपने कोड में नंगे 'सिवाय' खंडों का कभी भी उपयोग नहीं करना चाहिए। केवल NoChildExceptions उठाओ पकड़ो। बजाय इस बात का : प्रकार के सफलतापूर्वक नजरअंदाज कर दिया उठाया अपवाद: ZeroDivisionError प्रकार के सफलतापूर्वक नजरअंदाज कर दिया उठाया अपवाद: NameError प्रकार के सफलतापूर्वक नजरअंदाज कर दिया उठाया अपवाद: AttributeError प्रकार के सफलतापूर्वक नजरअंदाज कर दिया उठाया अपवाद: लेखन त्रुटि प्रकार के सफलतापूर्वक नजरअंदाज कर दिया उठाया अपवाद : ValueError सफलतापूर्वक पकड़ा गया NoChildException परीक्षण पूरा –

+0

@ IvanVulović तो आप जो चाहते हैं * केवल * पकड़ें 'NoChildException' (जो आपने पूछा है उसके ठीक विपरीत है), तो बस' कोशिश करें: ... को छोड़कर NoChildException: ... ', कुछ भी फैंसी की जरूरत नहीं है। –

2

मैं इसे स्वीकार किए गए उत्तर में सुधार के रूप में पेश करता हूं।

try: 
    dosomestuff() 
except MySpecialException: 
    ttype, value, traceback = sys.exc_info() 
    raise ttype, value, traceback 
except Exception as e: 
    mse = convert_to_myspecialexception_with_local_context(e, context) 
    raise mse 

यह दृष्टिकोण मूल स्टैकट्रेस बनाए रखने जब MySpecialException पकड़ा है, इसलिए जब अपने उच्चतम स्तर के अपवाद संचालक अपवाद लॉग आप ट्रैसबैक कि जहां मूल अपवाद उत्पन्न हुआ था के लिए अंक मिल जाएगा द्वारा स्वीकार कर लिया जवाब पर सुधार ।

0

मुझे एक संदर्भ मिला जिसमें सभी त्रुटियों को पकड़ना, लेकिन एक बुरी चीज नहीं है, अर्थात् यूनिट परीक्षण।

अगर मैं एक विधि है:

def test_my_method(): 
    try: 
     my_module.my_method() 
    except IOError, e: 
     print "shouldn't see this error message" 
     assert False 
    except Exception, e: 
     print "some other error message" 
     assert False 
    assert True 

क्योंकि आप अब पता चला है कि my_method सिर्फ एक अप्रत्याशित अपवाद दिए:

def my_method(): 
    try: 
     something() 
    except IOError, e: 
     handle_it() 

तो यह अनुग्राह्यतापूर्वक एक इकाई परीक्षण है कि लगता है कि हो सकता था।

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