在 python 中,如果它抛出错误,我如何重新 运行 一个函数
In python, how do I re-run a function if it throws an error
下面是我的代码片段,我想知道的是假设如果函数 main2() 由于某种原因抛出错误,我如何让我的异常再次出现 运行 相同的函数说 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
.
@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
如果你想让它健壮和干净,你应该选择第一个解决方案。您可以在大型企业项目中重复使用的第一个解决方案,由于退避时间,它可以在 backoff/delay 时间内考虑磁盘负载、用户负载网络问题。
如果你不使用延时,你将在一秒钟内完成所有 3 次尝试。这对于某些异常情况很好,但是当遇到网络问题或磁盘问题时,您需要更复杂的解决方案。
此外,考虑不要捕获所有异常,缓存所有异常是一种不好的做法。 More info, why it is bad
你可以试试
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
此代码将 运行 运行 main2()
直到出现 3 个错误,在前 2 个错误中它将再次循环 运行。
你应该处理特定函数内的所有错误,否则如果一起处理所有函数的错误,先于其他函数的函数将抛出错误并且控件将执行 except 块,跳过它下面的其余代码在 try 块中。
亲自尝试一下:
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
尝试以不同的顺序评论函数中出现的错误。
当在每个函数中处理错误时,每个函数都会被执行,而不会跳过循环中的其余函数
不幸的是,实施自定义 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 秒)。
使用该库,您可以采用任意数量的其他重试/延迟策略,包括指数退避、斐波那契、线性级数和多项式。您也可以自定义和创建自己的延迟策略。您可以合并自定义成功/失败处理程序,以及针对不同类型情况的不同替代路径。
当然,所有这些灵活性对于您的特定用例来说都太过分了——您不需要那么多。但它可能比担心 copying/pasting/maintaining 你自己的重试装饰器更容易,如果你发现你需要更复杂的重试策略,它会为你提供额外的内置选项。
如果有帮助,您可以在此处找到一些非常详细的文档:https://backoff-utils.readthedocs.io/en/latest/index.html
希望对您有所帮助!
下面是我的代码片段,我想知道的是假设如果函数 main2() 由于某种原因抛出错误,我如何让我的异常再次出现 运行 相同的函数说 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
.
@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
如果你想让它健壮和干净,你应该选择第一个解决方案。您可以在大型企业项目中重复使用的第一个解决方案,由于退避时间,它可以在 backoff/delay 时间内考虑磁盘负载、用户负载网络问题。
如果你不使用延时,你将在一秒钟内完成所有 3 次尝试。这对于某些异常情况很好,但是当遇到网络问题或磁盘问题时,您需要更复杂的解决方案。
此外,考虑不要捕获所有异常,缓存所有异常是一种不好的做法。 More info, why it is bad
你可以试试
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
此代码将 运行 运行 main2()
直到出现 3 个错误,在前 2 个错误中它将再次循环 运行。
你应该处理特定函数内的所有错误,否则如果一起处理所有函数的错误,先于其他函数的函数将抛出错误并且控件将执行 except 块,跳过它下面的其余代码在 try 块中。 亲自尝试一下:
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
尝试以不同的顺序评论函数中出现的错误。 当在每个函数中处理错误时,每个函数都会被执行,而不会跳过循环中的其余函数
不幸的是,实施自定义 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 秒)。
使用该库,您可以采用任意数量的其他重试/延迟策略,包括指数退避、斐波那契、线性级数和多项式。您也可以自定义和创建自己的延迟策略。您可以合并自定义成功/失败处理程序,以及针对不同类型情况的不同替代路径。
当然,所有这些灵活性对于您的特定用例来说都太过分了——您不需要那么多。但它可能比担心 copying/pasting/maintaining 你自己的重试装饰器更容易,如果你发现你需要更复杂的重试策略,它会为你提供额外的内置选项。
如果有帮助,您可以在此处找到一些非常详细的文档:https://backoff-utils.readthedocs.io/en/latest/index.html
希望对您有所帮助!