Python全局异常处理

Python全局异常处理,python,exception,Python,Exception,我想全局捕获键盘中断,并妥善处理它。我不想把我的整个脚本封装在一个巨大的try/except语句中。有什么方法可以做到这一点吗?您的脚本是否有您调用的函数来启动它 main() 那么就做: try: main() except: ... 如果你没有一个main,而只有一个逐行运行的巨大脚本,那么你应该把它放在main中,除了将整个脚本封装在main()函数中并用try]围绕它之外,没有其他方法可以做到这一点。除了块之外,这几乎是一样的: def main(): # Y

我想全局捕获
键盘中断
,并妥善处理它。我不想把我的整个脚本封装在一个巨大的try/except语句中。有什么方法可以做到这一点吗?

您的脚本是否有您调用的函数来启动它

main()
那么就做:

try:
    main()
except:
    ...

如果你没有一个
main
,而只有一个逐行运行的巨大脚本,那么你应该把它放在
main
中,除了将整个脚本封装在
main()
函数中并用
try]围绕它之外,没有其他方法可以做到这一点。除了
块之外,这几乎是一样的:

def main():
    # Your script goes here
    pass

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        # cleanup code here
        pass

如果这是一个在命令行上执行的脚本,您可以将运行时逻辑封装在
main()
中,在
中调用它,如果
并将其包装

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print 'Killed by user'
        sys.exit(0)
您也可以这样使用:

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)
输出:

waiting for 10 s
^CI just clicked on CTRL-C

注意:不要将信号的使用与线程混用。

如果您确实不想使用
try/except
,您可以更改
sys.excepthook

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

使用包含
sys.excepthook
原始值的
sys.excepthook
而不是手动保存它。很好;我没有意识到
sys.\uuuuu excepthook\uuuu
会保留旧值。保存旧值并调用它有一个优点,即可以链接多个
excepthook
s。这还会捕获由主线程生成的线程引发的异常吗?如前所述,这只会抑制由于键盘中断引起的中断。所有其他异常仍将导致与未更改
sys.excepthook
相同的行为。这不会处理除主线程外的其他线程中的未捕获异常。正如多接口所建议的,sys.excepthook是go@OrlinGeorgiev实际上,捕获信号应该是解决这个问题的答案。在python线程中使用信号没有问题。您只需要知道这样一个事实:您需要从主线程设置处理程序,并且它总是在主线程中执行。默认的
KeyboardInterrupt
异常也会从信号处理程序中引发。该建议是有效的,但没有其他方法是不正确的,如其他答案所示。