[英]raw_input() and sys.stdin misbehaves on CTRL-C
I am trying to detect a KeyboardInterrupt exception when CTRL-C is pressed during a raw_input() prompt. 我在raw_input()提示符期间按下CTRL-C时尝试检测KeyboardInterrupt异常。 Normally the following code works just fine to detect the command:
通常,以下代码可以正常检测命令:
try:
input = raw_input("Input something: ")
except KeyboardInterrupt:
do_something()
The problem comes when trying to intercept the input from sys.stdin. 尝试拦截sys.stdin的输入时出现问题。 After adding some code in between raw_input() and sys.stdin, the CTRL-C command now results in two exceptions: EOFError followed by KeyboardInterrupt a line or two later.
在raw_input()和sys.stdin之间添加一些代码之后,CTRL-C命令现在导致两个例外:EOFError后面跟随KeyboardInterrupt一行或两行。 This is the code used to test:
这是用于测试的代码:
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())
Which results in the following being printed out: 这导致打印出以下内容:
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
Am I missing something obvious? 我错过了一些明显的东西吗 Maybe intercepting the input in a bad way?
也许以不好的方式拦截输入?
Found this fairly old page which seems like the same issue. 找到这个相当老的页面,看起来像是同一个问题。 No solution though: https://mail.python.org/pipermail/python-list/2009-October/555375.html
但是没有解决方案: https : //mail.python.org/pipermail/python-list/2009-October/555375.html
Some environment details: Python 2.7.3 (64-bit), Windows 7 SP1 (64-bit) 一些环境细节:Python 2.7.3(64位),Windows 7 SP1(64位)
EDIT: An update to the readline method of StdinReplacement fixed the issue. 编辑: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'
It seems like the problem is that your readline
method returns an empty line, thus signaling the end of file: 似乎问题是你的
readline
方法返回一个空行,从而发出文件结束的信号:
import sys
class Test(object):
def readline(self):
return ''
sys.stdin = Test()
raw_input('') # EOFError!
However modifying it such that it doesn't return an empty line makes the code work: 但是,修改它以使它不返回空行使代码工作:
import sys
class Test(object):
def readline(self):
return '\n' # or 'a', or whatever
sys.stdin = Test()
raw_input('') # no error
The readline
method should return an empty string only when the file finished. readline
方法应该只在文件结束时返回一个空字符串。 The EOFError
is used to mean exactly this: raw_input
expected the file to contain a line, but the file ended. EOFError
用于表示这一点: raw_input
期望文件包含一行,但文件结束。
This is due to the call to PyFile_GetLine
found at the end of the implementation of raw_input
: 这是因为在
raw_input
的实现结束时调用了PyFile_GetLine
:
return PyFile_GetLine(fin, -1);
According to the documentation of PyFile_GetLine(PyObject *p, int n)
: 根据
PyFile_GetLine(PyObject *p, int n)
的文档:
If
n
is less than0
, however, one line is read regardless of length, butEOFError
is raised if the end of the file is reached immediately.但是,如果
n
小于0
,则无论长度如何都会读取一行,但如果立即到达文件末尾,则会EOFError
。
Since it passes -1
as n
the EOFError
is raised when the EOF
is found (ie you return an empty string from readline
). 由于它将
-1
作为n
传递,因此在找到EOF
时会EOFError
(即从readline
返回一个空字符串)。
As far as I can tell the behaviour you see is only possible if you insert the input and also create an interrupt. 据我所知,只有在插入输入并创建中断时才能看到行为。 Pressing only Ctrl + C doesn't generate any
EOFError
(at least on linux). 仅按Ctrl + C不会生成任何
EOFError
(至少在Linux上)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.