Python 异常后重新启动程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17533104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Restarting a program after exception
提问by vroomfondel
I have a program that queries an API every few seconds. Each response triggers a few functions which themselves make some calls to websites and such -- calls that I don't want to blindly trust to succeed. If I catch an exception in foo()
, for example, or even in a function that foo()
calls, is it possible to restart the program entirely in the except block? Essentially, I want to call queryRepeatedly()
upon an exception in one of its sub-functions, without keeping the previous call on the stack.
我有一个程序每隔几秒钟查询一个 API。每个响应都会触发一些函数,这些函数本身会调用网站等——我不想盲目相信这些调用会成功。foo()
例如,如果我foo()
在 . 本质上,我想queryRepeatedly()
在它的一个子函数中调用一个异常,而不是在堆栈上保留上一个调用。
Of course, I could return marker values and solve this another way, but the program is structured in a way such that the above approach seems much simpler and cleaner.
当然,我可以返回标记值并以另一种方式解决这个问题,但是程序的结构方式使上述方法看起来更简单和更清晰。
# 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()
Any suggestions are appreciated! Thanks.
任何建议表示赞赏!谢谢。
采纳答案by abarnert
To restart anything, just use a while
loop outsidethe try
. For example:
重新启动什么,只是用一个while
循环之外的try
。例如:
def foo():
while True:
try:
foo2()
except:
pass
else:
break
And if you want to pass the exception up the chain, just do this in the outer function instead of the inner function:
如果您想将异常传递到链上,只需在外部函数而不是内部函数中执行此操作:
def queryRepeatedly():
while True:
while True:
try:
foo()
bar()
baz()
except:
pass
else:
break
time.sleep(15)
def foo():
foo2()
All that indentation is a little hard to read, but it's easy to refactor this:
所有这些缩进有点难以阅读,但很容易重构:
def queryAttempt()
foo()
bar()
baz()
def queryOnce():
while True:
try:
queryAttempt()
except:
pass
else:
break
def queryRepeatedly():
while True:
queryOnce()
time.sleep(15)
But if you think about it, you can also merge the two while
loops into one. The use of continue
may be a bit confusing, but see if you like it better:
但仔细想想,也可以将两个while
循环合二为一。的使用continue
可能有点混乱,但看看你是否更喜欢它:
def queryRepeatedly():
while True:
try:
foo()
bar()
baz()
except:
continue()
time.sleep(15)
回答by sedavidw
In your exception make a recursive call
在您的异常中进行递归调用
except:
queryRepeatedly()
回答by djechlin
Refactor this - you'll get a stackoverflow error sooner or later if you have enough failures.
重构这个 - 如果你有足够的失败,你迟早会得到一个 stackoverflow 错误。
queryRepeatedly
should just be query
. It should return void
and throw exceptions on failures.
queryRepeatedly
应该只是query
。它应该返回void
并在失败时抛出异常。
Wrap in something that looks like this, your true queryRepeatedly
function?
包裹一些看起来像这样的东西,你的真正queryRepeatedly
功能?
while True:
try:
query()
except:
#handle
time.sleep(15)
All looping, no recursion needed.
全部循环,不需要递归。
Note that you must think carefully about how much of your program you need to restart. From your question it sounded like your actual problem was ensuring the query could try again if it sporadically fails, which is what my solution ensures. But if you want to clean up program resources - say, bounce SQL connections, which may have broken - then you need to think more carefully about how much of your program you need to "restart." In general you need to understand whyyour query failed to know what to fix, and in the extreme case, the right thing to do is an email or SMS to someone on call who can inspect the situation and write an appropriate patch or fix.
请注意,您必须仔细考虑需要重新启动多少程序。从您的问题来看,您的实际问题似乎是确保查询在偶尔失败时可以重试,这是我的解决方案所确保的。但是,如果您想清理程序资源——例如,反弹可能已断开的 SQL 连接——那么您需要更仔细地考虑需要“重新启动”多少程序。一般而言,您需要了解为什么您的查询不知道要修复什么,在极端情况下,正确的做法是发送电子邮件或短信给可以检查情况并编写适当补丁或修复的待命人员。
回答by Cody Krecicki
First make two files.
首先制作两个文件。
One file called run.py and one called forever.py and put them in the same folder.
一个名为 run.py 的文件和一个名为 forever.py 的文件,并将它们放在同一个文件夹中。
Go to your terminal within that folder and type chmod +x forever.py
转到该文件夹中的终端并输入chmod +x ever.py
run.py
运行文件
whatever code you want to run
forever.py
永远.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()
Open a terminal window from the folder and type this:
从文件夹中打开一个终端窗口并输入:
python3 ./forever.py retweet.py
python3 ./forever.py 转推.py
to start run.py and if it fails or has an exception, it'll just start over again.
启动 run.py,如果它失败或有异常,它会重新开始。
You now have a template to make sure if a file crashes or has an exception, you can restart it without being around. If this helps you, please give me a vote!
您现在有一个模板来确保文件崩溃或出现异常,您可以重新启动它而无需在身边。如果这对你有帮助,请给我投票!