input()和sys.stdin在CTRL上行为不当
我正在尝试在raw_input()提示符期间按CTRL-C时检测到KeyboardInterrupt异常。 通常,以下代码可以很好地检测命令:
try:
input = raw_input("Input something: ")
except KeyboardInterrupt:
do_something()
尝试拦截来自sys.stdin的输入时出现问题。 在raw_input()和sys.stdin之间添加一些代码之后,CTRL-C命令现在会导致两个例外:EOFError,后跟KeyboardInterrupt后面的一行或两行。 这是用于测试的代码:
import sys
import traceback
class StdinReplacement(object):
def __init__(self):
self.stdin = sys.stdin
sys.stdin = self
def readline(self):
input = self.stdin.readline()
# here something could be done with input before returning it
return input
if __name__ == '__main__':
rep = StdinReplacement()
while True:
info = None
try:
try:
input = raw_input("Input something: ")
print input
except:
info = sys.exc_info()
print info
except:
print 'n'
print "0:", traceback.print_traceback(*info)
print "1:", traceback.print_exception(*sys.exc_info())
这会导致以下内容被打印出来:
0:Traceback (most recent call last):
File "stdin_issues.py", line 19, in <module>
input = raw_input("Input something: ")
EOFError: EOF when reading a line
None
1:Traceback (most recent call last):
File "stdin_issues.py", line 23, in <module>
print info
KeyboardInterrupt
我错过了明显的东西吗? 可能以不好的方式拦截输入?
发现这个相当古老的页面,看起来像是同一个问题。 尽管没有解决方案:https://mail.python.org/pipermail/python-list/2009-October/555375.html
一些环境细节:Python 2.7.3(64位),Windows 7 SP1(64位)
-------------------------------------------------- ----------------------
编辑:对StdinReplacement的readline方法的更新修复了这个问题。
def readline(self):
input = self.stdin.readline()
# here something could be done with input before returning it
if len(input) > 0:
return input
else:
return 'n'
看来问题在于你的readline
方法返回一个空行,从而表示文件结束:
import sys
class Test(object):
def readline(self):
return ''
sys.stdin = Test()
raw_input('') # EOFError!
但是修改它以使其不返回空行将使代码正常工作:
import sys
class Test(object):
def readline(self):
return 'n' # or 'a', or whatever
sys.stdin = Test()
raw_input('') # no error
只有当文件完成时, readline
方法才会返回一个空字符串。 EOFError
用于表示这一点: raw_input
预期文件包含一行,但文件结束。
这是由于调用了在raw_input
实现结束时发现的PyFile_GetLine
:
return PyFile_GetLine(fin, -1);
根据PyFile_GetLine(PyObject *p, int n)
的文档:
但是,如果n
小于0
,则不管长度如何都会读取一行,但如果立即到达文件末尾,则会EOFError
。
由于它将n
作为n
传递-1
,因此发现EOF
时会EOFError
(即,您从readline
返回一个空字符串)。
据我所知,只有在插入输入并创建中断的情况下才能看到行为。 只按Ctrl + C不会产生任何EOFError
(至少在linux上)。