在广泛异常情况下未引发或捕获KeyboardInterrupt
有人能给我解释一下以下内容吗?我们先来看这段代码:
if __name__ == '__main__':
try:
while 1:
x = 2+2
except KeyboardInterrupt:
print('yo')
如果我运行这个代码,等一会儿,然后按下 Ctrl+C,就会处理一个异常,并且会打印出消息 yo
。
如果我们把代码改成捕获更广泛的异常,像这样:
if __name__ == '__main__':
try:
while 1:
x = 2+2
except Exception, e:
print('yo')
print(e)
运行它,等一会儿,再按 Ctrl+C,这个 KeyboardInterrupt 异常就不会被捕获。
根据 Python 的文档:
Python 默认安装了一小部分信号处理程序:SIGPIPE 会被忽略(这样在管道和套接字上的写入错误可以作为普通的 Python 异常报告),而 SIGINT 会被转换成 KeyboardInterrupt 异常。所有这些都可以被覆盖。
那么,为什么在第二种情况下,这个异常没有被捕获,甚至没有被抛出呢?
1 个回答
5
你不能通过捕获 Exception
来处理 KeyboardInterrupt
,因为前者只继承自 BaseException
。你可以在 文档中了解更多信息:
异常
KeyboardInterrupt
当用户按下中断键(通常是 Control-C 或 Delete)时会引发这个异常。在程序运行时,会定期检查是否有中断信号。如果在内置函数
input()
或raw_input()
等待输入时输入了中断信号,也会引发这个异常。这个异常是从BaseException
继承的,这样就不会被捕获Exception
的代码意外捕获,从而防止解释器无法正常退出。(强调是我的)
这意味着你需要这样做:
except BaseException, e:
但这被认为是一种不好的做法。更好的方法是直接捕获 KeyboardInterrupt
,就像你第一个例子中那样。