[英]How can i re-run a main() function in python, if one of its function throws an error?
[英]In python, how do I re-run a function if it throws an error
下面是我的代码片段,我想知道的是假设如果 function main2() 由于某种原因抛出错误,我如何让我的异常运行相同的 function 在它中断之前再次说 3 次?
在这里补充一下,任何函数都可能引发错误(不仅仅是 main2()),我可能不仅有 3 个函数,还有更多函数
import numpy as np
def main():
np.load('File.csv')
def main1():
np.load('File1.csv')
def main2():
np.load('File2.csv')
for i in range(1, 10):
try:
main()
main2()
main3()
except Exception as e:
print e
else:
break
这是一个你可以尝试的成语:
for _ in range(3): # try 3 times
try:
main2()
break # as soon as it works, break out of the loop
except Exception as e:
print e
continue # otherwise, try again
else: # if the loop exited normally, e.g. if all 3 attempts failed
pass
# do_something...
注意缩进。 这里的else
附加到for
,而不是try
。
您可以使用python 重试装饰器来做到这一点
@retry((Exception), tries=3, delay=0, backoff=0)
def main2():
np.load('File2.csv')
这与您编写的方式相同:
error_counter = 0
def main2():
try:
np.load('File2.csv')
except:
if error_counter < 3
error_counter += 1
main2()
raise Exception("Will not try again, have tried 3 times")
error_counter = 0
如果你想让它变得健壮和干净,你应该使用 go 作为第一个解决方案。 您可以在大型企业项目中重用的第一个解决方案,由于回退时间,它可以考虑磁盘负载、用户负载网络问题以及回退/延迟时间。
如果您不使用时间延迟,您将在一秒钟内完成所有 3 次尝试。 这对于某些例外情况很好,但是当遇到网络问题或磁盘问题时,您需要更复杂的解决方案。
此外,请考虑不要捕获所有异常,缓存所有异常是一种不好的做法。 更多信息,为什么不好
不幸的是,实现自定义retry
装饰器通常会有点痛苦。 如果你想调整它们的逻辑或调整它们,它实际上会很快变得相当复杂。 有一个名为Backoff-Utils的 Python 库,它支持非常健壮且易于扩展的重试/回退策略(完全披露:我有偏见,因为我是该库的作者)。
在您的假设问题中,您可以在基于装饰器的策略中使用该库:
from backoff_utils import backoff, apply_backoff, strategies
@apply_backoff(strategies.Fixed, max_tries = 3, catch_exceptions = [type(ValueError)])
def main2():
# np.load('File2.csv')
raise ValueError
print("In main2")
或者您可以在调用main2()
时在基于函数的策略中使用它:
result = backoff(main2,
max_tries = 3,
catch_exceptions = [type(ValueError)],
strategy = strategies.Fixed)
当然,上面的代码片段是专门为完全按照您上面描述的而设计的。 它使用线性策略(仅重试 3 次,尝试之间的默认延迟为 1 秒)。
使用该库,您可以采用任意数量的其他重试/延迟策略,包括指数退避、斐波那契、线性渐进和多项式。 您还可以自定义和创建自己的延迟策略。 您可以合并自定义成功/失败处理程序,以及针对不同类型情况的不同替代路径。
当然,所有这些灵活性对于您的特定用例来说都是多余的——您不需要那么多。 但它可能比担心复制/粘贴/维护自己的重试装饰器更容易,并且如果您发现以后需要更复杂的重试策略,它会为您提供额外的内置选项。
如果有帮助,您可以在此处找到一些非常详细的文档: https://backoff-utils.readthedocs.io/en/latest/index.html
希望这可以帮助!
你可以试试
for i in range(1, 10):
error_max = 3
error_counter = 0
try:
main()
try:
main2()
except Exception as e:
counter += 1
if counter == 3:
raise e
else:
continue
main3()
except Exception as e:
print e
else:
break
此代码将运行 function main2()
直到出现 3 个错误,并且在前 2 个错误将再次运行循环。
您应该处理特定函数内的所有错误,否则如果将所有函数的错误一起处理,则在其他函数之前的 function 将抛出错误,并且控件将执行 try 块中跳过其下方代码的除块 rest 的异常块。 自己试试:
def main():
# np.load('File.csv')
raise ValueError
print("In main")
def main1():
# np.load('File1.csv')
raise ValueError
print("In main1")
def main2():
# np.load('File2.csv')
raise ValueError
print("In main2")
for i in range(1, 10):
try:
main()
main2()
main3()
except Exception as e:
print(e)
else:
break
尝试以不同的顺序评论函数中引发的错误。 并且当在每个 function 中处理错误时,每个 function 都会执行,而不会跳过循环中的其余函数
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.