10

所有文档告诉我们的是,

当用户按下中断键(通常是Control-CDelete)时引发。在执行期间,会定期检查中断。

但是从代码的角度来看,我什么时候可以看到这个异常?它是否在语句执行期间发生?仅在语句之间?它可以发生在表达式的中间吗?

例如:

file_ = open('foo')
# <-- can a KeyboardInterrupt be raised here, after the successful
# completion of open but prior to the try? -->
try:
    # try some things with file_
finally:
    # cleanup

这段代码会在适当的时机泄漏KeyboardInterrupt吗?还是在某些语句或表达式的执行过程中引发?

4

2 回答 2

6

根据无关的PEP 343中的注释:

即使您编写没有错误的代码,KeyboardInterrupt 异常仍然可能导致它在任意两个虚拟机操作码之间退出。

所以它基本上可以发生在任何地方。它确实可以在评估单个表达式期间发生。(这应该不足为奇,因为表达式可以包含函数调用,并且在函数调用中几乎可以发生任何事情。)

于 2016-02-23T07:43:59.197 回答
2

是的,aKeyboardInterrupt可以出现在您标记的地方。

为了解决这个问题,你应该使用一个with块:

with open('foo') as file_:
    # do some things
    raise KeyboardInterrupt

# file resource is closed no matter what, even if a KeyboardInterrupt is raised

但是,即使在open()调用和对 的分配之间也可能发生异常file_。这可能不值得担心,因为通常 actrl-c将意味着您的程序即将结束,因此操作系统将清理“泄露”的文件句柄。但是如果您知道它很重要,您可以使用信号处理程序来捕获引发 KeyboardInterrupt (SIGINT) 的信号。

于 2016-02-23T07:42:24.240 回答