今天,我需要在Windows命令提示符下检查我的脚本运行情况[1],突然发现了一些奇怪的东西。我正在处理类似于这个的问题,但是这已经足以展示问题了。以下是代码。
def bing():
try:
raw_input()
except KeyboardInterrupt:
print 'This is what actually happened here!'
try: # pardon me for those weird strings
bing() # as it's consistent with everything in the chat room (see below)
print 'Yoo hoo...'
except KeyboardInterrupt:
print 'Nothing happens here too!'
这是情况:当脚本运行时,它会等待输入,用户应该按下Ctrl+C来触发KeyboardInterrupt
,然后被bing()
中的except
块捕获。所以,这应该是实际的输出。当我在Ubuntu终端和IDLE(在Windows和Ubuntu上)运行它时,就会发生这种情况。
This is what actually happened here!
Yoo hoo...
但是,在Windows命令提示符上,这并没有按预期进行。我得到了一个奇怪的输出。
This is what actually happened here! Nothing happens here too!
看起来一个KeyboardInterrupt
会传播到整个程序并最终终止它。
我尝试了我所能做的一切。首先,我使用了一个signal.signal
来处理SIGINT
(不起作用),然后我使用处理函数来引发一个稍后会捕获的Exception
(这也不起作用),然后事情变得比以前更加复杂了。所以,我回到了我那古老的try...catch
。然后,我去了Pythonist之间的房间。
@poke建议,当我们按下Ctrl+C时会引发一个EOFError
。然后,@ZeroPiraeus说,当人们按下Ctrl+Z和Enter时,会引发EOFError
。
那很有帮助,在几分钟的摆弄后,就开始了讨论。很快,一切都变成了混乱!有些结果是好的,有些是意外的,还有一些变得混乱不堪!
结论是停止使用Windows并让我的朋友们使用终端(我同意)。不过,我可以通过捕获EOFError
和KeyboardInterrupt
来进行解决。虽然每次按下Ctrl+Z和Enter都感觉很懒,但这对我来说不是一个大问题。但是,这对我来说是一种强迫症。
进一步的研究发现,当我在CMD中按下Ctrl+C时,没有引发KeyboardInterrupt
。
底部什么都没有。那么,这里到底发生了什么?为什么KeyboardInterrupt
会传播?有没有任何方法可以使输出与终端保持一致?
[1]: 我一直在终端上工作,但今天我需要确保我的脚本在所有平台上都能正常工作(特别是因为我的大多数朋友都不是程序员,只是坚持使用Windows)。