【问题标题】:Remove traceback in Python on Ctrl-C在 Ctrl-C 上删除 Python 中的回溯
【发布时间】:2011-08-16 03:16:40
【问题描述】:

当你点击 Ctrl+c 时,有没有办法阻止回溯出现, 即在 Python 脚本中引发 KeyboardInterrupt

【问题讨论】:

    标签: python traceback keyboardinterrupt


    【解决方案1】:
    import sys
    try:
        # your code
    except KeyboardInterrupt:
        sys.exit(0) # or 1, or whatever
    

    是最简单的方法,假设你得到一个Ctrl+c时还想退出。

    如果您想在没有尝试/例外的情况下捕获它,您可以使用 recipe like thissignal module,除非它在 ​​Windows 上似乎对我不起作用..

    【讨论】:

    • 鉴于 SIGINT 已发出信号,以状态 0 退出是根本错误的。理想情况下,必须保留返回的退出状态,就好像没有捕获异常一样。评论“or 1”不够好; 应为 1 的退出代码
    • @A-B-B 如果使用 Ctrl-C 退出程序不是标准的、非错误的退出方式,则预期退出代码为 1。如果此退出方法代表成功,则预期退出代码为零。仅仅因为以这种方式使用 Ctrl-C 可能是个坏主意并不意味着人们不会这样做(而且我已经使用过这样做的程序)。
    • 当然,但是在您的答案中包含退出代码 0 作为默认选项似乎仍然存在问题。
    • 这似乎干扰了input,至少在我的系统上是这样。尝试将input("Press enter to continue") 放入try 块中。当您按下回车键时,它只会将^M 打印到标准输出。 This 似乎相关。
    • @LondonRob 我刚刚尝试过,它对我来说确实很好用。阅读您链接的另一个问题,它似乎与此处的代码无关。你是说如果你用一个裸露的input 试试这个它可以工作,但如果你添加try 它不会?我认为其他的东西一定是不同的。
    【解决方案2】:

    试试这个:

    import signal
    import sys
    signal.signal(signal.SIGINT, lambda x, y: sys.exit(0))
    

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

    【讨论】:

    • 鉴于SIGINT 被触发,以状态0 退出是根本错误的。理想情况下,必须保留返回的退出状态,就好像没有捕获异常一样。
    • 不完全理解 lambda;你能解释一下这里使用“x,y:”而不是“x:”吗?
    • @Locane 是因为this,基本上signal.signal 的第二个参数是一个带有两个参数的函数'handler'。为清楚起见,x 和 y 可以像这样重命名 signal.signal(signal.SIGINT, lambda signal_number, current_stack_frame: sys.exit(0))
    • 我试图在 /usr/bin/openstack 上按 Ctrl-C 时停止堆栈跟踪,这种方法对我来说部分有效。在上一个答案中添加 try/except 解决方案大部分时间都有效,但有时我仍然会得到堆栈跟踪 - 可能是因为 /usr/bin/openstack 只是模块的包装器?
    • 不幸的是,sys.exit() 引发了 SystemExit,它产生了自己的回溯。尝试改用os._exit()
    【解决方案3】:

    赶上KeyboardInterrupt

    try:
        # do something
    except KeyboardInterrupt:
        pass
    

    【讨论】:

      【解决方案4】:

      用 try/except 块捕获它:

      while True:
         try:
            print "This will go on forever"
         except KeyboardInterrupt:
            pass
      

      【讨论】:

        【解决方案5】:

        另请注意,默认情况下,解释器退出时状态码为 128 + 您平台上的 SIGINT 值(在大多数系统上为 2)。

            import sys, signal
        
            try:
                # code...
            except KeyboardInterrupt: # Suppress tracebacks on SIGINT
                sys.exit(128 + signal.SIGINT) # http://tldp.org/LDP/abs/html/exitcodes.html
        

        【讨论】:

        • 如果中止说 shell 命令sleep 10,退出代码在我的系统上确实是 130。但是,在 Python 中引发 KeyboardInterrupt 时的退出代码只是 1。考虑 this closed bug。因此,我认为答案是不一致的。
        • 这是不正确的。使用信号 SIGINT 退出与使用代码 128 + SIGINT 退出不同。它们可能在您的 shell 中显示为相同的 $?,但它们在底层 API 中是可区分的并且具有不同的效果。例如,通常情况下,shell 脚本将在子进程以信号退出时停止执行,而不是在其以代码退出时停止执行。
        【解决方案6】:
        import sys
        try:
            print("HELLO")
            english = input("Enter your main launguage: ")
            print("GOODBYE")
        except KeyboardInterrupt:
            print("GET LOST")
        

        【讨论】:

          【解决方案7】:
          try:
              your_stuff()
          except KeyboardInterrupt:
              print("no traceback")
          

          【讨论】:

            【解决方案8】:

            使用context manager抑制异常:

            from contextlib import suppress
            
            def output_forever():
                while True:
                    print('endless script output. Press ctrl + C to exit')
            
            
            if __name__ == '__main__':
                with suppress(KeyboardInterrupt):
                    output_forever()
            

            【讨论】:

              猜你喜欢
              • 2012-09-10
              • 2021-10-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-12-02
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多