kar*_*boy 5 python signals try-except
我最近开始使用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"
Run Code Online (Sandbox Code Playgroud)
但如果我将信号处理改为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
Run Code Online (Sandbox Code Playgroud)
当我按ctrl + c时,两种情况下的异常存在差异.那么为什么会出现这种情况?
Python 有自己的内置信号处理程序SIGINT。该处理程序只是引发KeyboardInterrupt. 在您的第一个代码中,您将内置处理程序替换为新处理程序,因此您会看到以下输出:
$python test_exc.py
^Cinterrupted
Run Code Online (Sandbox Code Playgroud)
请注意,未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"
Run Code Online (Sandbox Code Playgroud)
你得到:
$python test_exc.py
^Cinterrupted
done
Run Code Online (Sandbox Code Playgroud)
请注意,点击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"
Run Code Online (Sandbox Code Playgroud)
示例运行:
$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
Run Code Online (Sandbox Code Playgroud)
注意:您可以通过访问默认信号处理程序signal.default_int_handler。
当您尝试在阻塞调用之后注册信号时sys.stdin.read,您实际上永远不会到达那里。
因此,当您按下 Ctrl-C 时,您会遇到异常,这会引发KeyboardInterrupt读取中断并被try.
当您在第一个示例中实际注册信号处理程序时,会发生一些略有不同的情况。中断正在由您的handleInt代码处理。