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

sor*_*rin 270 python exit traceback

我想知道如何退出Python而不在输出上有回溯转储.

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

我希望能够在exit(number)没有跟踪的情况下退出,但是在异常(不是退出)的情况​​下,我想要跟踪.

jkp*_*jkp 288

您可能遇到异常,程序正在退出(因为回溯).因此,要做的第一件事是在干净地退出之前捕获该异常(可能带有消息,给出示例).

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()
Run Code Online (Sandbox Code Playgroud)

  • 我*强烈建议删除`除了异常:`到`sys.exit(0)`,包括在内的行.在所有未处理的异常上打印回溯并在代码结束后退出已经是默认行为,那么为什么还要手动执行相同的操作呢? (12认同)
  • 如果在"main program stuff"中调用sys.exit(),则上面的代码会抛弃传递给sys.exit的值.请注意,sys.exit引发SystemExit,变量"e"将包含退出代码. (10认同)
  • @jkp - 关于你的评论:`sys.exit()`应该用于程序.`exit()`用于交互式shell.请参阅[Python中exit()和sys.exit()之间的区别?](http://stackoverflow.com/questions/6501121/the-difference-between-exit-and-sys-exit-in-python). (6认同)
  • 我建议在stderr sys.stderr.write(msg)中打印 (4认同)
  • 开头应该有类似"来自sys import import"的内容. (2认同)
  • @Pierre:但是按照这样的写法,它不会那样做——它会打印异常,然后退出,没有错误代码。这几乎与您想要的完全相反。 (2认同)
  • 据我所知,这个解决方案**仍然**在失败时提供回溯,不是吗?OP 想要退出**而不进行回溯**。 (2认同)

bst*_*rre 80

也许你正在尝试捕获所有异常,这是抓住了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
Run Code Online (Sandbox Code Playgroud)

通常,在except:不命名异常的情况下使用是一个坏主意.你会发现你不想捕捉的各种东西 - 比如SystemExit- 它也可以掩盖你自己的编程错误.我上面的例子很愚蠢,除非你在清理方面做些什么.您可以将其替换为:

import sys
sys.exit(1) # Or something that calls sys.exit().
Run Code Online (Sandbox Code Playgroud)

如果您需要退出而不提高SystemExit:

import os
os._exit(1)
Run Code Online (Sandbox Code Playgroud)

我这样做,在单元测试和调用下运行的代码fork().当分叉进程提升时,Unittest获取SystemExit.这绝对是一个极端的案例!

  • -1:这段代码很愚蠢:为什么要调用`SystemExit`来调用`sys.exit(e)`?删除两行具有*相同*效果.另外,清理属于`finally:`,而不是`除了Exception:... raise`. (3认同)
  • 抱歉,您是对的...我忘记了Python 2.5中对异常的重大重新组织。我试图撤消降级投票,但是只有在答案被编辑后,SO才允许我撤消。因此,既然我们处于2012年,并且Python 2.4是古老的历史,为什么不编辑它并预先显示正确的(当前)代码,而将2.5之前的方法留作脚注呢?它将大大改善答案,我将能够撤消下降投票,并将很乐意这样做。双赢:) (2认同)

rob*_*rob 9

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

  • @Val:又错了.它不会导致回溯 (8认同)
  • Downvote.它会抛出SystemExit,导致回溯 (4认同)
  • @Val:因为你没有使用标准的python控制台.Jython不是Python,看起来它(或者至少它的控制台)处理异常的方式不同. (3认同)

Ill*_*llI 8

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

import os
os._exit(1)
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此问题和相关答案.很惊讶为什么所有其他答案都如此过度简化.


RCr*_*oss 5

避免使用sys.exit()代替引发异常以允许程序干净地完成是更好的做法.如果要关闭回溯,只需使用:

sys.trackbacklimit=0
Run Code Online (Sandbox Code Playgroud)

您可以在脚本顶部设置此项以压缩所有回溯输出,但我更喜欢使用它,例如"已知错误",我希望输出是干净的,例如在文件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."
Run Code Online (Sandbox Code Playgroud)

如果捕获到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
Run Code Online (Sandbox Code Playgroud)

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