2013-10-22 5 views
21

क्या मैं अपवाद के बाद try-block निष्पादित करने के लिए वापस लौट सकता हूं? (लक्ष्य कम लिखना है) उदाहरण के लिए:पायथन पकड़ अपवाद और जारी रखने का प्रयास करें

try: 
    do_smth1() 
except: 
    pass 

try: 
    do_smth2() 
except: 
    pass 

बनाम

try: 
    do_smth1() 
    do_smth2() 
except: 
    ??? # magic word to proceed to do_smth2() if there was exception in do_smth1 
+0

आप बाधित होने पर एक 'try' ब्लॉक पर वापस नहीं आ सकते हैं, नहीं। –

+0

मुझे नहीं लगता। कुछ संरचना को प्रवाह को विभाजित करना होता है, और इस स्निपेट में 'do_smth2') निष्पादित करने के लिए अगला बिंदु निर्दिष्ट करें। – Jokester

+3

संभावित डुप्लिकेट [अपवादों पर "फिर से शुरू करें" के लिए एक पाइथोनिक तरीका?] (Http://stackoverflow.com/questions/18655481/a-pythonic-way-for-resume-next-on-exceptions) –

उत्तर

27

नहीं, आप ऐसा नहीं कर सकते। यही तरीका है कि पाइथन का सिंटैक्स है। एक बार जब आप अपवाद के कारण ट्राई-ब्लॉक से बाहर निकल जाएंगे, तो इसमें कोई रास्ता नहीं है।

हालांकि फॉर-लूप के बारे में क्या?

funcs = do_smth1, do_smth2 

for func in funcs: 
    try: 
     func() 
    except Exception: 
     pass # or you could use 'continue' 

नोट हालांकि यह है कि यह माना जाता है एक बुरा व्यवहार एक नंगे except है। आपको इसके बजाय एक विशिष्ट अपवाद के लिए पकड़ना चाहिए। मैंने Exception के लिए कब्जा कर लिया क्योंकि यह उतना अच्छा है जितना मैं जान सकता हूं कि विधियों को क्या अपवाद हो सकता है।

+0

कम से कम पकड़ अपवाद पर। यह सबसे अपवादों को पकड़ता है लेकिन सिस्टमएक्सिट और कीबोर्ड इंटरप्ट को अनदेखा करता है जिसे आप संभवतः अपने प्रोग्राम के शीर्ष स्तर पर छोड़कर कभी भी पकड़ना नहीं चाहते हैं। – Evan

4

आप अपने तरीकों के माध्यम से पुनरावृति सकता है ...

for m in [do_smth1, do_smth2]: 
    try: 
     m() 
    except: 
     pass 
1

मुझे नहीं लगता कि आप यह करते हैं करना चाहते हैं। सामान्य रूप से try कथन का उपयोग करने का सही तरीका यथासंभव सटीक है। मुझे लगता है कि यह बेहतर होगा करने के लिए:

def live_dangerously(fn, *args, **kw): 
    try: 
     return fn(*args, **kw) 
    except Exception: 
     pass 

live_dangerously(do_smth1) 
live_dangerously(do_smth2) 

लेकिन अन्य के रूप में:

try: 
    do_smth1() 
except Stmnh1Exception: 
    # handle Stmnh1Exception 

try: 
    do_smth2() 
except Stmnh2Exception: 
    # handle Stmnh2Exception 
1

जहां और कितनी बार आप ऐसा करने की जरूरत पर निर्भर करता है, तो आप भी एक समारोह है कि यह आप के लिए करता है लिख सकता है उत्तरों ने ध्यान दिया है, एक शून्य except आमतौर पर एक संकेत है जो आपके कोड के साथ कुछ और गलत है।

5

आप जो चाहते हैं उसे प्राप्त कर सकते हैं, लेकिन एक अलग वाक्यविन्यास के साथ। कोशिश/छोड़कर आप "आखिरकार" ब्लॉक का उपयोग कर सकते हैं। इस तरह से, पाइथन कोड के ब्लॉक को निष्पादित करेगा चाहे अपवाद फेंक दिया गया हो या नहीं।

इस तरह

:

try: 
    do_smth1() 
except: 
    pass 
finally: 
    do_smth2() 

लेकिन, यदि आप do_smth2 (निष्पादित करने के लिए) केवल तब अपवाद उत्पन्न नहीं कर रहा था चाहते हैं, एक "और" ब्लॉक का उपयोग करें:

try: 
    do_smth1() 
except: 
    pass 
else: 
    do_smth2() 

आप उन्हें मिश्रण कर सकते हैं भी, कोशिश/छोड़कर/अन्य/अंत में खंड में। मज़े करो!

3

एक तरीका जिसे आप इसे संभालने में एक जनरेटर के साथ है।समारोह को बुलाए जाने के बजाय, इसे उपज दें; तो जो कुछ भी जनरेटर लेने वाली है जनरेटर, या एक प्रहरी में इसे वापस बुला का परिणाम भेज सकते हैं अगर जनरेटर विफल रहा: ट्रैम्पोलिन कि ऊपर पूरा करता तो ऐसा दिखाई देगा:

def consume_exceptions(gen): 
    action = next(gen) 
    while True: 
     try: 
      result = action() 
     except Exception: 
      # if the action fails, send a sentinel 
      result = None 

     try: 
      action = gen.send(result) 
     except StopIteration: 
      # if the generator is all used up, result is the return value. 
      return result 

एक जनरेटर है कि संगत होगा इस के साथ इस प्रकार दिखाई देगा:

def do_smth1(): 
    1/0 

def do_smth2(): 
    print "YAY" 

def do_many_things(): 
    a = yield do_smth1 
    b = yield do_smth2 
    yield "Done" 
>>> consume_exceptions(do_many_things()) 
YAY 

ध्यान दें कि do_many_things() करता नहीं कॉल do_smth*, यह सिर्फ उन्हें पैदावार, और consume_exceptions उन्हें अपनी ओर से

12

पर कॉल जबकि अन्य उत्तर और स्वीकार किए जाते हैं एक सही हैं और वास्तविक कोड में पालन किया जाना चाहिए, बस पूर्णता और हास्य के लिए, तुम कोशिश कर सकते fuckitpy (https://github.com/ajalt/fuckitpy) मॉड्यूल।

आपका कोड निम्नलिखित बदला जा सकता है:

@fuckitpy 
def myfunc(): 
    do_smth1() 
    do_smth2() 

फिर बुला myfunc()do_smth2() कहेंगे भले ही में do_smth1())

नोट एक अपवाद है: कृपया नहीं किसी भी असली में यह कोशिश कोड, यह निंदा है

+0

यह एक आदर्श हैक है, यद्यपि आपने कहा था, निश्चित रूप से वास्तविक कोड में रिलीज़ नहीं किया जाना चाहिए। एकमात्र डाउन पॉइंट (जिसे मैंने चारों ओर काम करने में कामयाब नहीं किया है) यह है कि यह 'कोशिश/छोड़कर' विधियों के विपरीत वैश्विक चर तक नहीं पहुंच सकता है, या 'साथ बकवास: '(बकवास 'सजावट' बकवास के साथ 'से अधिक उपयोगी लगता है:')। – oliversm

0

special_func पुन: छोड़ने की कोशिश करने से बचने के लिए:

def special_func(test_case_dict): 
    final_dict = {} 
    exception_dict = {} 

    def try_except_avoider(test_case_dict): 

     try: 
      for k,v in test_case_dict.items(): 
       final_dict[k]=eval(v) #If no exception evaluate the function and add it to final_dict 

     except Exception as e: 
      exception_dict[k]=e #extract exception 
      test_case_dict.pop(k) 
      try_except_avoider(test_case_dict) #recursive function to handle remaining functions 

     finally: #cleanup 
      final_dict.update(exception_dict) 
      return final_dict #combine exception dict and final dict 

    return try_except_avoider(test_case_dict) 

भागो कोड:

def add(a,b): 
    return (a+b) 
def sub(a,b): 
    return (a-b) 
def mul(a,b): 
    return (a*b) 

case = {"AddFunc":"add(8,8)","SubFunc":"sub(p,5)","MulFunc":"mul(9,6)"} 
solution = special_func(case) 

आउटपुट लगता है:

{'AddFunc': 16, 'MulFunc': 54, 'SubFunc': NameError("name 'p' is not defined")} 

चर में बदलने के लिए:

:

locals().update(solution) 

चर कैसा लगेगा 210

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined") 
संबंधित मुद्दे