异常后重新启动程序

时间:2013-07-08 18:02:44

标签: python function

我有一个程序每几秒查询一次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 个答案:

答案 0 :(得分:18)

要重新启动任何内容,只需在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)

答案 1 :(得分:6)

重构这一点 - 如果你有足够的失败,你迟早会遇到堆栈溢出错误。

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

包装看起来像这样的东西,真正的queryRepeatedly函数?

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

所有循环,不需要递归。

请注意,您必须仔细考虑需要重启的程序数量。从您的问题来看,这听起来像您的实际问题是确保查询可以再次尝试,如果它偶尔失败,这是我的解决方案确保的。但是如果你想清理程序资源 - 比如反弹可能已经破坏的SQL连接 - 那么你需要更仔细地考虑你需要“重启”程序的程度。通常,您需要了解为什么您的查询无法知道要修复的内容,在极端情况下,正确的做法是向正在通话的人员发送电子邮件或短信,以便检查情况并撰写适当的补丁或修复。

答案 2 :(得分:0)

首先制作两个文件。

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

转到该文件夹​​中的终端,然后输入 chmod + x forever.py

run.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 retweet.py

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

您现在有了一个模板,以确保文件崩溃或发生异常,可以重新启动它而不必担心。如果这对您有帮助,请给我投票!

答案 3 :(得分:-4)

在您的例外中进行递归调用

except:
      queryRepeatedly()