在Ctrl-C上删除Python中的回溯

Kyl*_*iss 21 python keyboardinterrupt traceback

当你点击Ctrl+ c,即KeyboardInterrupt在Python脚本中加注时,有没有办法让追溯不会出现?

jle*_*ahy 33

试试这个:

import signal
import sys
signal.signal(signal.SIGINT, lambda x, y: sys.exit(0))
Run Code Online (Sandbox Code Playgroud)

这样您就不需要将所有内容都包装在异常处理程序中.

  • 在触发`SIGINT`的情况下退出状态0是根本错误的.理想情况下,必须保留返回的退出状态,就像未捕获到异常一样. (2认同)

agf*_*agf 25

import sys
try:
    # your code
except KeyboardInterrupt:
    sys.exit(0) # or 1, or whatever
Run Code Online (Sandbox Code Playgroud)

这是最简单的方法,假设您在获得Ctrl+ 时仍想退出c.

如果你想/陷阱它没有尝试除,你可以使用这样的配方使用的signal模块,但似乎为我工作在Windows上它不..

  • 鉴于发出 SIGINT 信号,以状态 0 退出从根本上是错误的。理想情况下必须保留返回的退出状态,就像没有捕获异常一样。注释“或 1”不够好;**预期退出代码为 1**。 (3认同)
  • 如果使用Ctrl-C退出程序不是标准的,非错误的方式,则@ABB预期退出代码为1。如果此退出方法表示成功,则期望的退出代码为零。仅仅因为以这种方式使用Ctrl-C可能不是一个好主意,并不意味着人们不这样做(而且我已经使用了这样做的程序)。 (2认同)
  • 当然,但在您的答案中包含退出代码 0 作为默认选择似乎仍然不确定。 (2认同)

ick*_*fay 6

赶上KeyboardInterrupt:

try:
    # do something
except KeyboardInterrupt:
    pass
Run Code Online (Sandbox Code Playgroud)


wim*_*wim 6

根据正确处理 SIGINT/SIGQUIT,如果您捕获 SIGINT,正确退出的唯一方法是随后使用 SIGINT 信号杀死自己(请参阅标题为“如何成为正确的程序”的部分)。尝试伪造正确的退出代码是不正确的。有关详细信息,另请查看为什么“执行退出 130 与死于 SIGINT 不同”?在 Unix Stack Exchange 上。

似乎这里所有退出零的答案实际上都表明程序行为不当。最好不要隐藏您被中断的情况,以便调用者(通常是 shell)知道该怎么做。

在 Python 中,stderr 上的回溯打印输出来自默认sys.excepthook行为。因此,为了抑制回溯垃圾邮件,我选择通过替换键盘中断上的 except 钩子来直接解决问题,然后通过重新引发原始异常来保留正确的退出代码:

import sys, time

def _no_traceback_excepthook(exc_type, exc_val, traceback):
    pass

def main():
    try:
        # whatever your program does here...
        print("hello world..")
        time.sleep(42)
    except KeyboardInterrupt:
        # whatever cleanup code you need here...
        print("bye")
        if sys.excepthook is sys.__excepthook__:
            sys.excepthook = _no_traceback_excepthook
        raise

if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

$ python3 /tmp/example.py
hello world..
^Cbye

$ echo $?
130
Run Code Online (Sandbox Code Playgroud)

如果您没有任何要执行的清理操作,并且您想要做的就是禁止在中断时打印回溯,那么默认安装它可能会更简单:

import sys

def _no_traceback_excepthook(exc_type, exc_val, traceback):
    if isinstance(exc_val, KeyboardInterrupt):
        return
    sys.__excepthook__(exc_type, exc_val, traceback)

sys.excepthook = _no_traceback_excepthook
Run Code Online (Sandbox Code Playgroud)