Repeat Python function call on exception?

后端 未结 7 678
抹茶落季
抹茶落季 2021-02-08 07:48

Hey everybody I\'m working on a data scraping project and I\'m looking for a clean way to repeat a function call if an exception is raised.

Pseudo-code:

         


        
相关标签:
7条回答
  • 2021-02-08 07:49

    To do precisely what you want, you could do something like the following:

    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
    

    Then you just wrap the old function in this new function:

    #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')
    
    0 讨论(0)
  • 2021-02-08 07:51

    Use a loop

    i = 0
    while True:
      try: myfunc(x); break;
      except myError:
        i = i + 1;
        # print "Trying again"
        if i > 5: raise myError2;
    
    0 讨论(0)
  • 2021-02-08 07:51
    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
    

    Hope this helps

    0 讨论(0)
  • 2021-02-08 07:57

    To raise Exception as usual after n retries

    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()
    
    0 讨论(0)
  • 2021-02-08 07:59

    I like to do these problems with recursion:

    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 讨论(0)
  • 2021-02-08 08:06
    
    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 讨论(0)
提交回复
热议问题