在正常输入下没有办法做到这一点。raw_input一次读取整行。在
在某些(极少数)情况下,您可以这样做:message = ''
while True:
ch = sys.stdin.read(1)
if ch == '\x1b':
exit(0)
elif ch == '\n':
break
message += ch
但总的来说,这行不通。例如,在一个典型的Unix系统上,sys.stdin将被行缓冲,甚至可能通过readline这样的库供用户编辑。或者,如果您在IDLE中运行程序,根本无法读取stdin;raw_input通过弹出一个对话框请求输入来解决这个问题,但是您的代码不能这样做。在
在不同的情况下,您可以在不同的平台上以不同的方式解决这个问题。在
在Windows上,如果您知道您的输入将是一个“DOS prompt”窗口(可以用^{}进行检查),则可以使用^{}函数。例如:
^{pr2}$
这应该适用于2.6+和3.3+,但在2.x中,与raw_input不同,它返回一个unicode,而不是str。如果您想要str,请删除所有u前缀,并使用getche而不是{}。在
在大多数具有合理标准termios的类似POSIX的平台上(包括macosx和Linux),如果您知道您的输入将是一个“TTY”(您可以用^{}进行检查),或者,如果您愿意,您可以只查找TTY来代替stdin,尽管这在很多平台上/在很多情况下都不起作用),您可以使用[termios](http://docs.python.org/3/library/termios.html)或^{}模块将输入置于“原始”模式。在python3.x中,您可能需要直接从^{}读取而不是{},并手动解码为Unicode。所以:import sys, termios, tty
assert sys.stdin.isatty(), "Can't run without a console to run on"
fd = sys.stdin.fileno()
stash = termios.tcgetattr(fd)
try:
tty.setraw(fd)
newterm = termios.tcgetattr(fd)
newterm[tty.LFLAG] |= termios.ECHO
termios.tcsetattr(fd)
message = b''
while True:
ch = sys.stdin.buffer.read(1)
if ch == b'\x1b':
exit(0)
elif ch == b'\n':
break
else:
message += ch
message = message.decode(sys.stdin.encoding)
finally:
termios.tcsetattr(fd, termios.TCSANOW, stash)
与Windows版本一样,这应该是2.6+/3.3+多版本兼容,除了它总是返回unicode,而2.xraw_input将返回str(在本例中,这都在decode行中,如果您不需要,可以删除它)。在
请注意,我在这里同时使用了tty和{}。tty模块是一个更高级别的包装器,但它并不能满足您的所有需要。因此,您可以尽可能地使用它(翻转在您的平台上获取raw模式所需的任何开关,并允许您对标志集和值使用跨平台/可读的名称,而不是索引),但是您通常仍然需要termios。在
在任何其他平台上,你都是自己的。在