我有一个python脚本,它包含一个大循环,读取一个文件并执行一些操作(我使用了几个包,比如urllib2、httplib2或beauthoulsoup)。在
看起来像这样:
try:
with open(fileName, 'r') as file :
for i, line in enumerate(file):
try:
# a lot of code
# ....
# ....
except urllib2.HTTPError:
print "\n >>> HTTPError"
# a lot of other exceptions
# ....
except (keyboardInterrupt, SystemExit):
print "Process manually stopped"
raise
except Exception, e:
print(repr(e))
except (KeyboardInterrupt, SystemExit):
print "Process manually stopped"
# some stuff
问题是程序在我按下Ctrl-C时停止,但是它没有被我的两个键盘中断异常捕捉到,尽管我确信它目前在循环中(因此至少在大try/except中)。在
怎么可能?一开始我以为这是因为我使用的一个包不能正确地处理异常(比如使用“except:”only),但如果是这样,我的脚本就不会停止。但剧本确实停了,至少应该有一个我的两个孩子抓住,不是吗?在
我哪里错了?在
提前谢谢!在
编辑:
在try-except后面添加了一个finally:
子句,并在两个try-except块中打印回溯,当我点击Ctrl-C时,它通常会显示None
,但我曾经设法得到这个(似乎它来自urllib2,但我不知道这是否是我无法捕获键盘中断的原因):
回溯(最近一次呼叫):
^{pr2}$
很可能是在脚本位于try块之外时发出CTRL-C,因此无法捕获信号。在
我已经在我对这个问题的评论中指出,这个问题很可能是由问题中遗漏的代码部分引起的。但是,确切的代码不应该相关,因为当Python代码被Ctrl-C中断时,Python通常会抛出一个
KeyboardInterrupt
异常您在评论中提到使用
boilerpipe
Python包。这个Python包使用JPype
创建到Java的语言绑定。。。我可以用下面的Python程序重现您的问题:如果用Ctrl-C中断该程序,则不会引发异常。程序似乎会立即终止,这样Python解释器就没有机会抛出异常。当
boilerpipe
的导入被删除时,问题就消失了。。。在带有
^{pr2}$gdb
的调试会话表明,如果导入boilerpipe
,Python启动了大量线程:没有
boilerpipe
导入的gdb
会话:所以我假设您的Ctrl-C信号在另一个线程中被处理,或者
jpype
做了其他一些奇怪的事情,破坏了对Ctrl-C的处理编辑:作为一种可能的解决方法,您可以注册一个信号处理程序,该处理程序在您按Ctrl-C时接收到的
SIGINT
信号。即使导入了boilerpipe
和JPype
,信号处理程序也会被激发。这样,当用户点击Ctrl-C时,您将得到通知,您将能够在程序的中心点处理该事件。如果希望在此处理程序中终止脚本,可以终止该脚本。否则,一旦信号处理程序函数返回,脚本将在中断的地方继续运行。参见以下示例:相关问题 更多 >
编程相关推荐