Python全局异常处理

Kye*_*e R 46 python exception

所以我想抓住KeyboardInterrupt全球,并妥善处理它.我不想把我的整个脚本包含在一个巨大的try/except语句中,因为这听起来很糟糕.有没有办法做到这一点?

mul*_*ces 110

sys.excepthook如果你真的不想使用,你可以改变try/except.

import sys
def my_except_hook(exctype, value, traceback):
    if exctype == KeyboardInterrupt:
        print "Handler code goes here"
    else:
        sys.__excepthook__(exctype, value, traceback)
sys.excepthook = my_except_hook
Run Code Online (Sandbox Code Playgroud)

  • 使用`sys .__ excepthook__`,其中包含`sys.excepthook`的原始值,而不是手动保存它. (8认同)
  • 保存旧的并调用它的优点是可以链接几个`excepthook`s. (3认同)
  • 这也会捕获由主线程产生的线程抛出的异常吗? (3认同)
  • 如所写,这仅抑制了由于“ KeyboardInterrupt”而引起的中断。其他所有异常仍将导致相同的行为,就像未更改sys.excepthook一样。 (2认同)

Rob*_*wie 24

如果这是一个在命令行上执行的脚本,则可以将运行时逻辑封装在一起main(),将其调用if __name__ == '__main__'并包装.

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print 'Killed by user'
        sys.exit(0)
Run Code Online (Sandbox Code Playgroud)

  • 除了您的主线程之外,这不会处理其他线程中未捕获的异常。正如多重接口所建议的那样,sys.excepthook是必经之路 (2认同)

mou*_*uad 12

你也可以使用这样的信号:

import signal, time

def handler(signum, frame):
    print 'I just clicked on CTRL-C '

signal.signal(signal.SIGINT, handler)

print "waiting for 10 s"
time.sleep(10)
Run Code Online (Sandbox Code Playgroud)

输出:

waiting for 10 s
^CI just clicked on CTRL-C
Run Code Online (Sandbox Code Playgroud)

注意:不要将信号与线程混合使用.

  • 实际上,捕获信号应该是对此的答案。 (2认同)
  • 在python线程中使用信号是没有问题的。您只需要知道这样一个事实:您需要从主线程设置处理程序,并且它始终在主线程中执行。默认的“KeyboardInterrupt”异常也是从信号处理程序引发的。 (2认同)

Cla*_*diu 8

您的脚本是否具有您启动它的功能?

main()
Run Code Online (Sandbox Code Playgroud)

然后就是:

try:
    main()
except:
    ...
Run Code Online (Sandbox Code Playgroud)

如果你没有一个main只是一个逐行运行的巨大脚本,那么你应该把它放在一个main.