Python 中的重试函数

新手上路,请多包涵

前段时间,我需要 R 中的 retry 函数来处理缓慢的服务器响应。该函数将具有以下行为:(尝试一个操作(函数或方法),如果失败,稍等片刻,然后重试)x10

我想出了以下内容:

 retry <- function(fun, max_trys = 10, init = 0){
  suppressWarnings(tryCatch({
    Sys.sleep(0.3);
    if(init<max_trys) {fun}
}, error=function(e){retry(fun, max_trys, init = init+1)}))}

它运作良好。现在我在 Python3 中需要相同的代码,所以我尝试编写相同的代码:

 import time
def retry_fun(fun, max_trys = 10, init=0):
    try:
        time.sleep(0.3)
        if(init<max_trys):
            fun
    except:
        retry_fun(fun, max_trys, init = init+1)

但是当我运行它时,它使我的内核崩溃。由于我是 Python 的初学者,我不确定是什么导致了崩溃,以及是否/如何将一个函数作为参数传递给另一个函数。

你能帮帮我吗?

原文由 François M. 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 676
2 个回答

除了能够传递函数并通过在名称后添加 () 来使用它们(Python 的调用语法),您 不需要 使用递归;只是把它放在一个循环中:

 import time
def retry(fun, max_tries=10):
    for i in range(max_tries):
        try:
           time.sleep(0.3)
           fun()
           break
        except Exception:
            continue

except Exception 应该更改为捕获函数可能引发的有意义的异常。使用 Exception (正如我在示例中所做的那样)通常是不好的做法,因为它会捕获大量您可能不想捕获的异常。

除此之外,使用 for-loop 而不是显式的第三个计数器和递归(这会导致大值的长调用堆栈)更好。

原文由 Dimitris Fasarakis Hilliard 发布,翻译遵循 CC BY-SA 3.0 许可协议

有几个 Python 包:

  1. 后退
  2. 韧性

退避示例

import backoff

@backoff.on_exception(backoff.expo,
                      (MyPossibleException1,
                       MyPossibleException2))
def your_function(param1, param2):
    # Do something

坚韧的榜样

from tenacity import wait_exponential, retry, stop_after_attempt

@retry(wait=wait_exponential(multiplier=2, min=2, max=30),  stop=stop_after_attempt(5))
def your_function(param1, param2):
   # Do something

原文由 Medhat Gayed 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题