在广泛异常的情况下不会引发或捕获键盘中断

Dmi*_*sev 3 python signals python-2.7

有人可以向我解释以下内容。让我们来看看代码:

if __name__ == '__main__':
    try:
        while 1:
            x = 2+2
    except KeyboardInterrupt:
        print('yo')
Run Code Online (Sandbox Code Playgroud)

如果我运行这个,稍等片刻,然后按Ctrl+ C,将处理异常并yo打印消息。

如果我们更改代码以捕获像这样的广泛异常:

if __name__ == '__main__':
    try:
        while 1:
            x = 2+2
    except Exception, e:
        print('yo')
        print(e)
Run Code Online (Sandbox Code Playgroud)

运行它,稍等片刻,按Ctrl+ C,不会捕获到 KeyboardInterrupt 异常。

根据Python 文档

Python 默认安装少量信号处理程序:忽略 SIGPIPE(因此管道和套接字上的写入错误可以报告为普通 Python 异常)并且SIGINT 被转换为 KeyboardInterrupt 异常。所有这些都可以被覆盖。

那么,为什么在第二种情况下这个异常没有被捕获甚至引发?

小智 5

你不能通过捕捉KeyboardInterrupt来捕捉,Exception因为前者BaseException只继承自。您可以在文档中阅读有关此内容的信息:

例外 KeyboardInterrupt

当用户按下中断键(通常是 Control-C 或 Delete)时引发。在执行期间,会定期检查中断。内置函数input()raw_input()等待输入时输入的中断也会引发此异常。异常继承自,BaseException以免被捕获的代码意外捕获Exception,从而防止解释器退出。(强调我的)

这意味着您必须执行以下操作:

except BaseException, e:
Run Code Online (Sandbox Code Playgroud)

但这被认为是一种不好的做法。最KeyboardInterrupt好像在第一个示例中那样捕获自己。