使python在按下ESC键时立即退出程序
我正在做一个算法,从键盘读取输入,将其存储在名为message的变量中,然后将该变量写入文件。但是,每当用户输入时,如果他按ESC键,我希望执行停止,没有任何错误 假设代码是:使python在按下ESC键时立即退出程序,python,pypy,Python,Pypy,我正在做一个算法,从键盘读取输入,将其存储在名为message的变量中,然后将该变量写入文件。但是,每当用户输入时,如果他按ESC键,我希望执行停止,没有任何错误 假设代码是: message = raw_input() 我还需要补充什么?所以如果我在一个句子的中间,比如: My name is th 当我按下ESC键时,它就会停止?用正常的输入无法做到这一点原始输入每次读取整行 在某些(极少数)情况下,您可以执行以下操作: message = '' while True: ch =
message = raw_input()
我还需要补充什么?所以如果我在一个句子的中间,比如:
My name is th
当我按下ESC键时,它就会停止?用正常的输入无法做到这一点<代码>原始输入每次读取整行 在某些(极少数)情况下,您可以执行以下操作:
message = ''
while True:
ch = sys.stdin.read(1)
if ch == '\x1b':
exit(0)
elif ch == '\n':
break
message += ch
但总的来说,这是行不通的。例如,在典型的Unix系统上,sys.stdin
将进行行缓冲,甚至可能通过readline
之类的库进行输入,以允许用户在进行编辑。或者,如果您在空闲状态下运行程序,则根本无法读取stdin
raw_input
通过弹出一个对话框请求输入来解决这个问题,但您的代码不能这样做
在不同的情况下,您可以在不同的平台上以不同的方式解决这个问题
在Windows上,如果您知道您的输入将是一个“DOS提示符”窗口(您可以查看该窗口),则可以使用这些函数。例如:
import sys, msvcrt
assert sys.stdin.isatty(), "Can't run without a console to run on"
message = u''
while True:
ch = msvcrt.getwche()
if ch == u'\x1b':
exit(0)
elif ch == u'\n':
break
message += ch
这应该适用于2.6+和3.3+,但在2.x中,与raw_input
不同,它返回的是unicode
,而不是str
。如果您想在此处使用str
,请删除所有u
前缀,并使用getche
而不是getwche
在大多数POSIX类平台上(包括Mac OS X和Linux),如果您知道您的输入将是一个“TTY”(您可以使用TTY进行检查,或者,如果您愿意,您可以寻找一个TTY来代替stdin,尽管这在很多平台上/在很多情况下都不起作用),您可以使用
[termios
]()或模块将输入置于“原始”模式。在Python3.x中,您可能需要直接从而不是从sys.stdin中读取,并手动解码为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
和termios
。tty
模块是一个更高级别的包装器,但它并没有完成您想要的一切。因此,您可以尽可能地使用它(在您的平台上翻转获得原始模式所需的任何开关,并允许您对标志集和值使用跨平台/可读名称,而不是索引),但您通常仍然需要termios
在任何其他平台上,您都只能靠自己。使用正常输入无法做到这一点<代码>原始输入每次读取整行 在某些(极少数)情况下,您可以执行以下操作:
message = ''
while True:
ch = sys.stdin.read(1)
if ch == '\x1b':
exit(0)
elif ch == '\n':
break
message += ch
但总的来说,这是行不通的。例如,在典型的Unix系统上,sys.stdin
将进行行缓冲,甚至可能通过readline
之类的库进行输入,以允许用户在进行编辑。或者,如果您在空闲状态下运行程序,则根本无法读取stdin
raw_input
通过弹出一个对话框请求输入来解决这个问题,但您的代码不能这样做
在不同的情况下,您可以在不同的平台上以不同的方式解决这个问题
在Windows上,如果您知道您的输入将是一个“DOS提示符”窗口(您可以查看该窗口),则可以使用这些函数。例如:
import sys, msvcrt
assert sys.stdin.isatty(), "Can't run without a console to run on"
message = u''
while True:
ch = msvcrt.getwche()
if ch == u'\x1b':
exit(0)
elif ch == u'\n':
break
message += ch
这应该适用于2.6+和3.3+,但在2.x中,与raw_input
不同,它返回的是unicode
,而不是str
。如果您想在此处使用str
,请删除所有u
前缀,并使用getche
而不是getwche
在大多数POSIX类平台上(包括Mac OS X和Linux),如果您知道您的输入将是一个“TTY”(您可以使用TTY进行检查,或者,如果您愿意,您可以寻找一个TTY来代替stdin,尽管这在很多平台上/在很多情况下都不起作用),您可以使用
[termios
]()或模块将输入置于“原始”模式。在Python3.x中,您可能需要直接从而不是从sys.stdin中读取,并手动解码为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
和termios
。tty
模块是一个更高级别的包装器,但它并没有完成您想要的一切。因此,您可以尽可能地使用它(在您的平台上翻转获得原始模式所需的任何开关,并允许您对标志集和值使用跨平台/可读名称,而不是索引),但您通常仍然需要termios
在任何其他平台上,您都可以自己使用。原始输入不是这样工作的。它等待用户按下enter键,以传递用户写入变量消息的内容。你需要的东西,将监测每一个键按下,然后如果关键是ESC键,它可以做一些事情,如退出程序。如果您使用的是linux,请查看kbhit。顺便问一下,是否有理由将其标记为
pypy
?据我所知,PyPy 2.1.0/2.7.3在输入方面与CPython 2.7.3完全相同,并且相同