【发布时间】:2011-06-04 03:56:52
【问题描述】:
我正在 Windows 上编写 python 2.6.6 代码,如下所示:
try:
dostuff()
except KeyboardInterrupt:
print "Interrupted!"
except:
print "Some other exception?"
finally:
print "cleaning up...."
print "done."
dostuff() 是一个永远循环的函数,从输入流中一次读取一行并对其进行操作。当我按下 ctrl-c 时,我希望能够停止它并进行清理。
相反,except KeyboardInterrupt: 下的代码根本没有运行。唯一会打印的是“清理...”,然后会打印如下所示的回溯:
Traceback (most recent call last):
File "filename.py", line 119, in <module>
print 'cleaning up...'
KeyboardInterrupt
因此,异常处理代码没有运行,并且回溯声称在 finally 子句期间发生了键盘中断,这没有意义,因为按 ctrl-c 是导致该部分运行的原因首先!甚至通用的 except: 子句也没有运行。
编辑:基于 cmets,我将 try: 块的内容替换为 sys.stdin.read()。问题仍然完全按照描述发生,finally: 块的第一行运行,然后打印相同的回溯。
编辑 #2: 如果我在读取后添加了几乎任何内容,则处理程序将起作用。所以,这失败了:
try:
sys.stdin.read()
except KeyboardInterrupt:
...
但这有效:
try:
sys.stdin.read()
print "Done reading."
except KeyboardInterrupt:
...
这是打印的内容:
Done reading. Interrupted!
cleaning up...
done.
因此,出于某种原因,“阅读完毕”。行被打印,即使异常发生在前一行。这不是一个真正的问题——显然我必须能够在“try”块内的任何地方处理异常。但是,打印无法正常工作 - 之后它不会像预期的那样打印换行符! “Interrupted”打印在同一行......之前有一个空格,出于某种原因......?无论如何,在那之后代码会做它应该做的事情。
在我看来,这是在阻塞系统调用期间处理中断的错误。
【问题讨论】:
-
显示你的 dostuff() 的代码,因为这个代码应该可以工作(而且确实)
-
它在 Python 2.5.1 中按预期工作。
-
用 Python 2.7 转载,将
dostuff()替换为sys.stdin.read() -
我也可以在 Win7 x64 上使用 Python 2.6.6、2.7.1 和 3.1.3 重现这一点。在
print "Interrupted!"之后插入sys.stdout.flush()也没有改变任何东西。 -
在 Win7 64 位操作系统上的 python 2.6.5 32 位解释器上复制。将 do_stuff() 替换为 sys.stdin.read()。 ctl-c 后的第一个输出是“清理...”
标签: python windows keyboardinterrupt