2012-02-21 24 views
11

मैंने कार्यों का एक समूह बनाया है और मुझे उन सभी में खंडों को छोड़कर बहुत समान की आवश्यकता है, लेकिन मुझे कोशिश की इतनी सारी लाइनें और क्लॉज और प्रत्येक फ़ंक्शन के अंदर एक ही कोड को छोड़कर नफरत है। उदाहरण के लिए:दोहराव कोशिश करें और खंडों को छोड़कर

import sys 
import random 

def foo(): 
    num=random.random() 
    try: 
     if num>0.5: print 'OK' 
     elif num>0.25: raise NameError('Too Small') 
     else: raise KeyboardInterrupt 
    except NameError: 
     print "%s had a NameError" % sys._getframe().f_code.co_name 
    except: 
     print "%s had a different Error" % sys._getframe().f_code.co_name 

def bar(): 
    num=random.random() 
    try: 
     if num>0.8: print 'OK' 
     elif num>0.6: raise NameError('Too Small') 
     else: raise KeyboardInterrupt 
    except NameError: 
     print "%s had a NameError" % sys._getframe().f_code.co_name 
    except: 
     print "%s had a different Error" % sys._getframe().f_code.co_name 

"कोशिश" के बाद कोड कार्यों के लिए अलग है, लेकिन "छोड़कर" के बाद कोड समान है। मैं बयान को छोड़कर उन लोगों को समेकित करना चाहता हूं ताकि वे मेरा कोड इतना खराब न हो जाएं। क्या ऐसा करने का कोई अच्छा तरीका है?

+1

किसी भी अपवाद को पकड़ना आम तौर पर वास्तव में एक बुरा विचार है। यह वास्तविक समस्याओं का मुखौटा बनाता है और डीबगिंग को कठिन बना देता है। आप जिन अपवादों के बारे में जानते हैं उन्हें पकड़ें - यदि आप उनके बारे में नहीं जानते हैं, तो क्या आप वास्तव में उन्हें पकड़ना चाहते हैं? –

+0

यह एक अच्छा मुद्दा है। अगर फ़ंक्शन विफल हो जाता है, तो मुझे आगे बढ़ने के लिए स्क्रिप्ट की आवश्यकता होती है। अंतिम "छोड़कर" में 'प्रिंट sys.exc_info() [: 2]' शामिल है जिसमें अपवाद का नाम शामिल है। क्या ऐसा करने के लिए इससे अच्छा तरीका है? – crunkchitis

उत्तर

22

Python Decorators जो आप चाहते हैं वो हैं।

आपने कहा कि ब्लॉक को छोड़कर हमेशा एक ही होता है। एक कस्टम सजावट करें जो आप चाहते हैं। आपको इसे प्रत्येक फ़ंक्शन/विधि पर लागू करना होगा, लेकिन यह निश्चित रूप से डुप्लिकेशंस को सहेजता है।

def handleError(function): 
    def handleProblems(): 
     try: 
      function() 
     except Exception: 
      print "Oh noes" 
    return handleProblems 


@handleError 
def example(): 
    raise Exception("Boom!") 

जब डेकोरेटर के साथ एक विधि बुला लागू:

 
>>> 
>>> example() 
Oh noes 
>>> 

आप आप क्या करते हैं के रूप में अपवाद प्रकार बदलने के लिए और साथ ही आवश्यकता होगी, लेकिन आप जहां मैं साथ जा रहा हूँ के jist मिल इस।

+0

भयानक। इसके लिए धन्यवाद। – crunkchitis

+0

@ क्रंककाइटिस आपका स्वागत है। – Finglas

+2

यह एक अच्छा उदाहरण नहीं है क्योंकि सजावट उन कार्यों के लिए काम नहीं करेगा जो तर्क लेते हैं। – user3467349

6

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

def foo(): 
    num=random.random() 
    if num>0.5: print 'OK' 
    elif num>0.25: raise NameError('Too Small') 
    else: raise KeyboardInterrupt 

def bar(): 
    num=random.random() 
    if num>0.8: print 'OK' 
    elif num>0.6: raise NameError('Too Small') 
    else: raise KeyboardInterrupt 

def try_numerics(f): 
    try: 
     f() 
    except NameError: 
     print "%s had a NameError" % sys._getframe().f_code.co_name 
    except: 
     print "%s had a different Error" % sys._getframe().f_code.co_name 

# In your main code... 
if (need_to_run_foo): 
    try_numerics(foo) 
elif (need_to_run_bar): 
    try_numerics(bar) 
2

यदि वे आपके वास्तविक कार्य हैं तो उन्हें सामान्यीकृत करना आसान होगा। को छोड़कर:

आप एक सामान्य समारोह

def general(bottom_num, top_num): 
    num=random.random() 
    try: 
    if num>top_num: print 'OK' 
    elif num>bottom_num: raise NameError('Too Small') 
    else: raise KeyboardInterrupt 
    except NameError: 
    print "%s had a NameError" % sys._getframe().f_code.co_name 
    except: 
    print "%s had a different Error" % sys._getframe().f_code.co_name 

इस दोहरा से अपने कोड रखने के लिए और पते का प्रयास होगा बना सकते हैं इस मुद्दे

5

जवाब ऊपर कार्य है कि तर्क ले के लिए लागू नहीं होता है - के लिए बाद में मामला है, मुझे लगता है कि आप कुछ इस तरह चाहेगा:

def handleError(f): 
    def handleProblems(*args, **kwargs): 
     try: 
      return f(*args, **kwargs) 
     except Exception: 
      print "Oh noes" 
    return handleProblems 

हम यह इतना तरह का परीक्षण कर सकते हैं:

@handleError 
def addTwo(x, y): 
    print(x + y) 

>>> addTwo(5,5) 
10 
>>> addTwo(5, 's') 
Oh noes 
0

मैं हाल ही में एक ही परिदृश्य में भाग गया, मेरे मामले में मेरे पास कुछ कस्टम अपवाद हैं जिन पर मुझे अपवाद को लॉग या बढ़ाने की आवश्यकता है। मैंने प्रकार के अनुसार अपवादों को संभालने के लिए एक सजावटी विधि बनाई है।

try: 
    obj.some_method() 
except Exception as e: 
    catch_and_log_exception(e) 


def catch_and_log_exception(e): 
    if isinstance(e, MyConnectionError): 
     print "Connection error : %s." % e.message 
     sys.exit(1) 
    elif isinstance(e, MyConnectionTimeout): 
     print "Connection to server has been timed out. %s" % e.message 
     sys.exit(1) 
    elif isinstance(e, MyException): 
     message = e.explanation if e.explanation else e.message 
     log_error_message(str(message)) 
     print "Failed, please check the logs." 
     sys.exit(1) 
    else: 
     raise e 

इस सहायता की आशा करें !!