19

我有一个每隔几秒钟查询一次 API 的程序。每个响应都会触发一些函数,这些函数本身会调用网站等——我不想盲目相信会成功的调用。例如,如果我在中捕获异常foo(),甚至在foo()调用的函数中捕获异常,是否可以完全在 except 块中重新启动程序?本质上,我想queryRepeatedly()在其子函数之一中调用异常,而不将先前的调用保留在堆栈中。

当然,我可以返回标记值并以另一种方式解决这个问题,但是程序的结构使得上述方法看起来更简单、更清晰。

# Sample "main" function that I want to call
def queryRepeatedly():
    while True:
        foo()
        bar()
        baz()
        time.sleep(15)

def foo():
    # do something
    try:
        foo2() # makes a urllib2 call that I don't trust
    except:
        #restart queryRepeatedly

queryRepeatedly()

任何建议表示赞赏!谢谢。

4

4 回答 4

29

要重新启动任何内容,while只需. try例如:

def foo():
    while True:
        try:
            foo2()
        except:
            pass
        else:
            break

如果你想将异常向上传递,只需在外部函数而不是内部函数中执行此操作:

def queryRepeatedly():
    while True:
        while True:
            try:
                foo()
                bar()
                baz()
            except:
                pass
            else:
                break
        time.sleep(15)

def foo():
    foo2()

所有这些缩进有点难以阅读,但很容易重构:

def queryAttempt()
    foo()
    bar()
    baz()

def queryOnce():
    while True:
        try:
            queryAttempt()
        except:
            pass
        else:
            break

def queryRepeatedly():
    while True:
        queryOnce()
        time.sleep(15)

但是如果你仔细想想,你也可以将两个while循环合并为一个。的使用continue可能有点混乱,但看看你是否更喜欢它:

def queryRepeatedly():
    while True:
        try:
            foo()
            bar()
            baz()
        except:
            continue()
        time.sleep(15)
于 2013-07-08T18:05:54.427 回答
6

重构这个 - 如果你有足够的失败,你迟早会得到一个 stackoverflow 错误。

queryRepeatedly应该只是query。它应该返回void并在失败时抛出异常。

包裹在看起来像这样的东西中,你的真正queryRepeatedly功能是什么?

while True:
    try:
        query()
    except:
        #handle
    time.sleep(15)

所有循环,不需要递归。

请注意,您必须仔细考虑需要重新启动程序的多少。从您的问题看来,您的实际问题是确保查询在偶尔失败时可以重试,这是我的解决方案所确保的。但是,如果您想清理程序资源——例如,可能已经中断的反弹 SQL 连接——那么您需要更仔细地考虑您需要“重新启动”多少程序。一般来说,您需要了解为什么您的查询无法知道要修复什么,并且在极端情况下,正确的做法是向值班人员发送电子邮件或短信,以便他们检查情况并编写适当的补丁或修复程序。

于 2013-07-08T18:06:17.597 回答
0

首先制作两个文件。

一个名为 run.py 的文件和一个名为 forever.py 的文件,并将它们放在同一个文件夹中。

转到该文件夹​​中的终端并键入chmod +x forever.py

运行.py

whatever code you want to run

永远的.py

#!/usr/local/lib/python3.7
from subprocess import Popen
import sys

filename = sys.argv[1]
while True:
    print("\nStarting " + filename)
    p = Popen("python3 " + filename, shell=True)
    p.wait()

从文件夹中打开一个终端窗口并输入:

python3 ./forever.py 转推.py

启动 run.py,如果它失败或有异常,它将重新开始。

您现在有一个模板来确保如果文件崩溃或出现异常,您可以在不离开的情况下重新启动它。如果这对你有帮助,请给我投票!

于 2020-03-01T04:50:12.020 回答
-3

在您的异常中进行递归调用

except:
      queryRepeatedly()
于 2013-07-08T18:06:17.273 回答