繁体   English   中英

在 python 中,如果抛出错误,我该如何重新运行 function

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM