5

我最近开始使用 python 。当我遇到这种行为时,我正在处理键盘中断

import signal,sys

def handleInt(sign,no):
    print "interrupted"

signal.signal(signal.SIGINT,handleInt)    # exception raised is IOError

try:
    sys.stdin.read(1)
except IOError:
    print "io interrupt"

但是如果我将信号处理更改为在 try-except 之后

import signal,sys

def handleInt(sign,no):
    print "interrupted"

try:
    sys.stdin.read(1)
except KeyboardInterrupt:
    print "keyboard interrupt"

signal.signal(signal.SIGINT,handleInt)    # exception raised is KeyboardInterrupt

当我按 ctrl+c 时,两种情况下的异常存在差异。那么为什么会出现这种行为?

4

2 回答 2

5

Python 有自己的内置信号处理程序,用于SIGINT. 这个处理程序只是简单地提出KeyboardInterrupt. 在您的第一个代码中,您将内置处理程序替换为新处理程序,因此您会看到以下输出:

$python test_exc.py 
^Cinterrupted

请注意,io interrupted没有打印出来,因为没有引发异常实际上将代码修改为:

import signal,sys

def handleInt(sign,no):
    print "interrupted"

signal.signal(signal.SIGINT, handleInt)    # exception raised is IOError

try:
    sys.stdin.read(1)
except IOError:
    print "io interrupt"
else:
    # else is executed only if no exception was raised
    print "done"

你得到:

$python test_exc.py 
^Cinterrupted

done

请注意,点击Ctrl+C不会阻止调用,sys.stdin.read(1)因此您仍然必须按一些键才能让程序继续。在信号处理程序中引发异常将引发它,就好像调用sys.stdin.read(1)产生它一样:

import signal,sys

def handleInt(sign,no):
    print "interrupted"
    raise OSError

signal.signal(signal.SIGINT, handleInt)    # exception raised is IOError

try:
    sys.stdin.read(1)
except IOError:
    print "io interrupt"
else:
    # else is executed only if no exception was raised
    print "done"

样品运行:

$python test_exc.py 
^Cinterrupted
Traceback (most recent call last):
  File "test_exc.py", line 10, in <module>
    sys.stdin.read(1)
  File "test_exc.py", line 5, in handleInt
    raise OSError
OSError

注意:您可以通过signal.default_int_handler.

于 2013-07-26T09:58:46.043 回答
1

当您在阻塞调用后尝试注册信号时sys.stdin.read,您实际上永远不会到达那里。

因此,当您按下 Ctrl-C 时会出现异常,这会引发KeyboardInterrupt读取中断并被try.

当您在第一个示例中实际注册信号处理程序时,会发生一些稍微不同的事情。中断正在由您的handleInt代码处理。

于 2013-07-26T09:55:20.793 回答