ChatGPT解决这个技术问题 Extra ChatGPT

如何在没有回溯的情况下退出 Python?

我想知道如何在没有输出回溯转储的情况下退出 Python。

我仍然希望能够返回错误代码,但我不想显示回溯日志。

我希望能够在没有跟踪的情况下使用 exit(number) 退出,但如果出现异常(不是退出),我想要跟踪。

sys.exit() 在不打印回溯的情况下停止执行,引发异常确实......您的问题准确地描述了默认行为是什么,所以不要更改任何内容。
@Luper 很容易检查 sys.exit() 是否抛出 SystemExit!
我说它不会打印回溯,并不是说它不会引发异常。
我认为这确实回答了您提出的问题:stackoverflow.com/questions/173278/…
这个问题是专门针对 Jython 2.4 还是类似的问题?因为对于现代版本的 Python(即使在 2009 年,这意味着 CPython 2.6 和 3.1、Jython 2.5 和 IronPython 2.6),这个问题没有意义,而且最重要的答案是错误的。

m
martineau

您可能遇到了异常,因此程序正在退出(带有回溯)。因此,首先要做的是在干净退出之前捕获该异常(可能带有消息,给出示例)。

在您的 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()

开头应该有“from sys import exit”之类的东西。
如果在“主程序内容”中调用 sys.exit(),上面的代码会丢弃传递给 sys.exit 的值。请注意 sys.exit 引发 SystemExit 并且变量“e”将包含退出代码。
我建议在 stderr sys.stderr.write(msg) 中打印
强烈建议删除从 except Exception:sys.exit(0) 的行,包括在内。在所有未处理的异常上打印回溯并在代码结束后退出已经是默认行为,那么为什么还要手动执行相同的操作呢?
@jkp - 关于您的评论:sys.exit() 应该用于程序。 exit() 用于交互式 shell。请参阅The difference between exit() and sys.exit() in Python?
M
Martijn Pieters

也许您正试图捕捉所有异常,而这正是捕捉由 sys.exit() 引发的 SystemExit 异常?

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 下运行并调用 fork() 的代码中执行此操作。当分叉的进程引发 SystemExit 时,单元测试得到。这绝对是一个极端案例!


-1:这段代码很傻:为什么捕获 SystemExit 只是为了调用 sys.exit(e)?删除这两行具有 same 效果。此外,清理属于 finally:,而不是 except Exception: ... raise
@MestreLion:您可以随意投反对票,但是如果您阅读了我的评论就在您的评论上方,那仅适用于2.5+。如果您阅读了我的所有帖子,我明确表示代码很愚蠢,并准确地建议了您在评论中所说的内容。
抱歉,你是对的……我忘记了 Python 2.5 中对异常进行了重大重组。我试图撤消反对票,但只有在编辑答案时才允许我这样做。那么,既然我们是在 2012 年,而 Python 2.4 是古老的历史,为什么不编辑它并预先显示正确的(当前)代码,而将 2.5 之前的方法作为脚注呢?它将大大改善答案,我将能够撤消反对票,并且很乐意这样做。人人共赢:)
@MestreLion:我按照你的建议开始编辑,但这个答案真的只在问题的上下文和 2.4 环境中才有意义。否决票并没有让我感到不安。
W
Wojciech Bederski
import sys
sys.exit(1)

I
IlliakaillI

以下代码不会引发异常,并且会在没有回溯的情况下退出:

import os
os._exit(1)

See this question and related answers 了解更多详情。很惊讶为什么所有其他答案都如此复杂。

这也不会进行适当的清理,例如调用清理处理程序、刷新 stdio 缓冲区等(感谢 pabouk 指出这一点)


不适合正常出口。此解决方案绕过所有 Python 清理代码!
r
rob

import sys; sys.exit(0) 之类的东西?


@mestreLion 那我为什么会得到 Dets 06 18:53:17 Traceback(最近一次调用最后):文件“debug_new.py”,第 4 行,在 import sys; sys.exit(0) SystemExit: 0 at org.python.core.PyException.fillInStackTrace(PyException.java:70) 在我的控制台中?
@Val:因为您没有使用标准的 python 控制台。 Jython 不是 Python,看起来它(或至少它的控制台)以不同的方式处理异常。
R
RCross

避免使用 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

如果发生任何其他错误,我们仍然会获得完整的回溯输出。


有关在 Python 3 中使用 sys.trackbacklimit,请参阅 this answer
请将错误消息发送到 stderr,而不是 stdout。改用这个:print("Process failed", file=sys.stderr)
M
Miled Louis Rizk

使用内置的 python 函数 quit() 就是这样。无需导入任何库。我正在使用 python 3.4


请不要在您的代码中使用 quit()exit()。这些函数仅适用于交互式 Python。请参阅 Python exit commands - why so many and when should each be used? 您可以改用 sys.exit()raise SystemExit
K
Karl W.

我会这样做:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)

佚名

关于什么

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

没有回溯,并且以某种方式更明确。


B
Brian Zimmerman
# 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

如果您要评论代码,它将提高答案的质量。