我正在尝试用Python进行一个操作,如果它在某些方面失败了,我想重试10次。如果它以任何其他方式失败,我希望它立即失败。在10次重试后,我希望所有的失败都传播到调用者。在
我无法以令人满意的方式编写流控制代码。下面是一个行为示例(但不是样式!)我想要:
def run():
max_retries = 10
for retry_index in range(max_retries):
try:
result = run_operation()
except OneTypeOfError:
if retry_index < max_retries - 1:
continue
else:
raise
if result.another_type_of_error:
if retry_index < max_retries - 1:
continue
else:
raise AnotherTypeOfError()
try:
result.do_a_followup_operation()
except AThirdTypeOfError:
if retry_index < max_retries - 1:
continue
else:
raise
return result
raise Exception("We don't expect to end up here")
一开始我以为我可以重构它,这样重试逻辑就和错误处理逻辑分开了。问题是,例如,如果OneTypeOfError由结果:做后续手术(),在这种情况下,我根本不想重试。我只想在上面编码的特定情况下重试。在
如果我认为这是一个可重构的异常,那么这个异常是否可以返回到一个ryable函数中。不知怎么的,在我看来,这并没有上面说的那么优雅。在
我想知道Python中是否有任何流控制模式可以在这里有所帮助。在
如果我理解正确的话,您可以通过改变两件事来完成以下操作:
从10开始计算
tries_left
,而不是从0开始向上计算retry_index
,这样读起来更自然,并且可以利用正数是真实的。如果您更改(或包装)},则可以合并前两个
run_operation()
使其已经在AnotherTypeOfError
为真时引发{except
块。通过省略
raise
之后的else
(或者如果您选择测试if tries_left
,则在continue
之后)可以使代码稍微更密集一点——控制流无论如何都在该点被转移,并且通过将一个简单的语句放在与没有else
的空if
同一行。在编辑:啊,我没有意识到你的代码表明你没有使用多个except块,正如JETM所指出的那样
以下是异常处理的快速入门:
很久以前我就这样做过一次,并且递归地在一种异常中调用同一个函数,而不是另一种异常。我还向函数传递了retry index和max\u retries变量,这意味着将它们作为参数添加。在
另一种方法是将整个过程放在一个for循环中,循环的max_retries,并在所有块中添加一个break,用于您不希望重试的异常。在
最后,代替for循环,您可以将整个事件放入while循环中,为一种类型的异常在except块中插入一个增量条件,并在except块中为其他异常设置while条件为false。在
您可以使用一个特定的异常类和递归来稍微简单一点。大致如下:
具有给定迭代次数的迭代解决方案在语义上似乎有问题。毕竟,你希望整件事都成功,而重试是一种退步。在我看来,重试次数不够听起来像是个基本情况。在
相关问题 更多 >
编程相关推荐