问题:如何从Python退出而无需追溯?
我想知道如何在不对输出进行回溯转储的情况下退出Python。
我仍然希望能够返回错误代码,但是我不想显示回溯日志。
我希望能够exit(number)
不使用跟踪而退出,但是如果发生异常(不是退出),我需要跟踪。
I would like to know how to I exit from Python without having an traceback dump on the output.
I still want want to be able to return an error code but I do not want to display the traceback log.
I want to be able to exit using exit(number)
without trace but in case of an Exception (not an exit) I want the trace.
回答 0
您大概遇到了一个异常,因此程序正在退出(带有追溯)。因此,要做的第一件事是在干净退出之前捕获该异常(可能带有消息,给出示例)。
在您的main
例程中尝试以下操作:
import sys, traceback
def main():
try:
do main program stuff here
....
except KeyboardInterrupt:
print "Shutdown requested...exiting"
except Exception:
traceback.print_exc(file=sys.stdout)
sys.exit(0)
if __name__ == "__main__":
main()
You are presumably encountering an exception and the program is exiting because of this (with a traceback). The first thing to do therefore is to catch that exception, before exiting cleanly (maybe with a message, example given).
Try something like this in your main
routine:
import sys, traceback
def main():
try:
do main program stuff here
....
except KeyboardInterrupt:
print "Shutdown requested...exiting"
except Exception:
traceback.print_exc(file=sys.stdout)
sys.exit(0)
if __name__ == "__main__":
main()
回答 1
也许您正在尝试捕获所有异常,而这正在捕获由SystemExit
引发的异常sys.exit()
?
import sys
try:
sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
sys.exit(e)
except:
# Cleanup and reraise. This will print a backtrace.
# (Insert your cleanup code here.)
raise
通常,except:
不命名而使用异常是一个坏主意。您会遇到各种不想要的东西-例如SystemExit
-并且它也可能掩盖您自己的编程错误。上面的示例很愚蠢,除非您要进行清理。您可以将其替换为:
import sys
sys.exit(1) # Or something that calls sys.exit().
如果您不退出就退出SystemExit
:
import os
os._exit(1)
我使用在unittest和call下运行的代码来执行此操作fork()
。当分叉过程出现时,单元测试就会进行SystemExit
。这绝对是一个极端的情况!
Perhaps you’re trying to catch all exceptions and this is catching the SystemExit
exception raised by sys.exit()
?
import sys
try:
sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
sys.exit(e)
except:
# Cleanup and reraise. This will print a backtrace.
# (Insert your cleanup code here.)
raise
In general, using except:
without naming an exception is a bad idea. You’ll catch all kinds of stuff you don’t want to catch — like SystemExit
— and it can also mask your own programming errors. My example above is silly, unless you’re doing something in terms of cleanup. You could replace it with:
import sys
sys.exit(1) # Or something that calls sys.exit().
If you need to exit without raising SystemExit
:
import os
os._exit(1)
I do this, in code that runs under unittest and calls fork()
. Unittest gets when the forked process raises SystemExit
. This is definitely a corner case!
回答 2
回答 3
像import sys; sys.exit(0)
什么?
something like import sys; sys.exit(0)
?
回答 4
以下代码将不会引发异常,并且会在没有回溯的情况下退出:
import os
os._exit(1)
有关更多详细信息,请参见此问题和相关答案。惊讶为什么所有其他答案都如此复杂。
The following code will not raise an exception and will exit without a traceback:
import os
os._exit(1)
See this question and related answers for more details. Surprised why all other answers are so overcomplicated.
回答 5
最好避免使用sys.exit(),而是引发/处理异常以使程序清晰地完成,这是更好的做法。如果要关闭回溯,只需使用:
sys.trackbacklimit=0
您可以在脚本的顶部设置此设置以压缩所有回溯输出,但是我更倾向于少用它,例如我希望输出干净的“已知错误”,例如在文件foo.py中:
import sys
from subprocess import *
try:
check_call([ 'uptime', '--help' ])
except CalledProcessError:
sys.tracebacklimit=0
print "Process failed"
raise
print "This message should never follow an error."
如果捕获到CalledProcessError,则输出将如下所示:
[me@test01 dev]$ ./foo.py
usage: uptime [-V]
-V display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1
如果发生任何其他错误,我们仍将获得完整的追溯输出。
It’s much better practise to avoid using sys.exit() and instead raise/handle exceptions to allow the program to finish cleanly. If you want to turn off traceback, simply use:
sys.trackbacklimit=0
You can set this at the top of your script to squash all traceback output, but I prefer to use it more sparingly, for example “known errors” where I want the output to be clean, e.g. in the file foo.py:
import sys
from subprocess import *
try:
check_call([ 'uptime', '--help' ])
except CalledProcessError:
sys.tracebacklimit=0
print "Process failed"
raise
print "This message should never follow an error."
If CalledProcessError is caught, the output will look like this:
[me@test01 dev]$ ./foo.py
usage: uptime [-V]
-V display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1
If any other error occurs, we still get the full traceback output.
回答 6
使用内置的python函数quit()就是这样。无需导入任何库。我正在使用python 3.4
Use the built-in python function quit() and that’s it.
No need to import any library.
I’m using python 3.4
回答 7
我会这样:
import sys
def do_my_stuff():
pass
if __name__ == "__main__":
try:
do_my_stuff()
except SystemExit, e:
print(e)
I would do it this way:
import sys
def do_my_stuff():
pass
if __name__ == "__main__":
try:
do_my_stuff()
except SystemExit, e:
print(e)
回答 8
关于什么
import sys
....
....
....
sys.exit("I am getting the heck out of here!")
没有回溯,并且以某种方式更加明确。
What about
import sys
....
....
....
sys.exit("I am getting the heck out of here!")
No traceback and somehow more explicit.
回答 9
# Pygame Example
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('IBM Emulator')
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
fontObj = pygame.font.Font('freesansbold.ttf', 32)
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)
textRectObj = textSurfaceObj.get_rect()
textRectObj = (10, 10)
try:
while True: # main loop
DISPLAYSURF.fill(BLACK)
DISPLAYSURF.blit(textSurfaceObj, textRectObj)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
except SystemExit:
pass
# Pygame Example
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('IBM Emulator')
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
fontObj = pygame.font.Font('freesansbold.ttf', 32)
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)
textRectObj = textSurfaceObj.get_rect()
textRectObj = (10, 10)
try:
while True: # main loop
DISPLAYSURF.fill(BLACK)
DISPLAYSURF.blit(textSurfaceObj, textRectObj)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
except SystemExit:
pass