2011-01-22 19 views
10

अरे सभी मैं डेटा स्क्रैपिंग प्रोजेक्ट पर काम कर रहा हूं और यदि कोई अपवाद उठाया गया है तो मैं फ़ंक्शन कॉल को दोहराने के लिए एक साफ तरीका ढूंढ रहा हूं।अपवाद पर पायथन फ़ंक्शन कॉल दोहराएं?

छद्म कोड:

try: 
    myfunc(x) 
except myError: 
    ###try to call myfunc(x) again Y number of times, 
     until success(no exceptions raised) otherwise raise myError2 

मुझे पता है यह सब पर सबसे अच्छा अभ्यास नहीं है, लेकिन मैं अलग कोड/नेटवर्क परतों कि विश्वसनीय नहीं हैं की एक संख्या के माध्यम से काम कर रहा हूँ और मैं वास्तविक नहीं कर सकते उन्हें डीबग करें।

अभी मैं इसे कोशिश करने के एक विशाल सेट के साथ पूरा कर रहा हूं \ ब्लॉक को छोड़कर और यह मेरी आंखों को खून कर रहा है।

सुरुचिपूर्ण विचार किसी को भी?

+1

यह एक ऐसी स्थिति है, जहां एक गोटो अविश्वसनीय रूप से उपयोगी होगा है। –

+8

@ राफ: नहीं, यह वास्तव में नहीं होगा। –

+4

['__past__ आयात goto' से]] (http://entrian.com/goto/) – AndiDog

उत्तर

11

ठीक आप क्या चाहते करने के लिए, आप निम्नलिखित की तरह कुछ कर सकता है का उपयोग करें:

import functools 
def try_x_times(x, exceptions_to_catch, exception_to_raise, fn): 
    @functools.wraps(fn) #keeps name and docstring of old function 
    def new_fn(*args, **kwargs): 
     for i in xrange(x): 
      try: 
       return fn(*args, **kwargs) 
      except exceptions_to_catch: 
       pass 
     raise exception_to_raise 
    return new_fn 

तो फिर तुम सिर्फ लपेट इस नए समारोह में पुराना कार्य:

#instead of 
#risky_method(1,2,'x') 
not_so_risky_method = try_x_times(3, (MyError,), myError2, risky_method) 
not_so_risky_method(1,2,'x') 

#or just 
try_x_times(3, (MyError,), myError2, risky_method)(1,2,'x') 
+2

\ _ \ _ name \ _ \ _ को बदलने के बजाय functools.wraps का उपयोग करें। –

+0

@Fred इसका उपयोग करने के लिए अपडेट किया गया। – user470379

+2

कूल। मैं वास्तव में http://peter-hoffmann.com/2010/retry-decorator-python.html का उपयोग कर समाप्त हुआ लेकिन यह काफी वही विचार है। – Haipa

0

टुकड़ा निम्न प्रयास करें:

while True: 
    try: 
     func() 
     break 
    except: 
     print "Error. Gonna try again" 

लेकिन यह बेहतर है पुनर्प्रयास की संख्या को सीमित करने के लिए।

+0

'को छोड़कर: 'अधिकांश (* लेकिन सभी *) मामलों में कोई अच्छा विचार नहीं है। मैं 'अपवाद को छोड़कर' का उपयोग करना चाहूंगा: '। और यह निश्चित रूप से मानता है कि 'func() 'बिल्कुल समाप्त हो जाएगा। – AndiDog

8

एक पाश

i = 0 
while True: 
    try: myfunc(x); break; 
    except myError: 
    i = i + 1; 
    # print "Trying again" 
    if i > 5: raise myError2; 
+0

शायद आप का मतलब है I> 5. :) –

0
success = False 
attempts = 0 
while not success and attempts < 10: # or however many times you want to attempt 
    try: 
     functionCall() 
     success = True 
    except: 
     i += 1 
if not success: 
    raise functionCallFailedError 

आशा इस मदद करता है

4

for x in xrange(num_retries): 
    try: 
     myFunc() 
    except MyError, err: 
     continue 
     #time.sleep(1) 
    err = None 
    break 
if err: 
    raise MyError2 
#else: 
# print "Success!" 


+0

बस जो मैं खोज रहा था। धन्यवाद! –

1

मैं प्रत्यावर्तन के साथ इन समस्याओं करना पसंद:

def tryfor(times, on_failure, excepts, func, *args, **kwargs): 
    if times < 1: 
     raise on_failure() 
    try: 
     return func(*args, **kwargs) 
    except excepts: 
     return tryfor(times-1, on_failure, excepts, func, *args, **kwargs) 


tryfor(3, PermanentException, (SomeError,), dostuff,1,2) 
0

हमेशा की तरह अपवाद को बढ़ाने के लिए के बाद n पुनः प्रयास करता

from functools import wraps 

def retry(times): 
    """ 
    Decorator to retry any functions 'times' times. 
    """ 
    def retry_decorator(func): 
     @wraps(func) 
     def retried_function(*args, **kwargs): 
      for i in range(times - 1): 
       try: 
        func(*args, **kwargs) 
        return 
       except Exception: 
        pass 
      func(*args, **kwargs) 

     return retried_function 

    return retry_decorator 


# test 

attempts = 3 

@retry(4) 
def function_that_raises_error(): 
    global attempts 
    if 0 < attempts: 
     print("fail") 
     attempts -= 1 
     raise Exception 

    print("pass") 

function_that_raises_error() 
संबंधित मुद्दे