def read_single_keypress():
"""Waits for a single keypress on stdin.
This is a silly function to call if you need to do it a lot because it has
to store stdin's current setup, setup stdin for reading single keystrokes
then read the single keystroke then revert stdin back after reading the
keystroke.
Returns the character of the key that was pressed (zero on
KeyboardInterrupt which can happen when a signal gets handled)
"""
import termios, fcntl, sys, os
fd = sys.stdin.fileno()
# save old state
flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
attrs_save = termios.tcgetattr(fd)
# make raw - the way to do this comes from the termios(3) man page.
attrs = list(attrs_save) # copy the stored version to update
# iflag
attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
| termios.ISTRIP | termios.INLCR | termios. IGNCR
| termios.ICRNL | termios.IXON )
# oflag
attrs[1] &= ~termios.OPOST
# cflag
attrs[2] &= ~(termios.CSIZE | termios. PARENB)
attrs[2] |= termios.CS8
# lflag
attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
| termios.ISIG | termios.IEXTEN)
termios.tcsetattr(fd, termios.TCSANOW, attrs)
# turn off non-blocking
fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
# read a single keystroke
try:
ret = sys.stdin.read(1) # returns a single character
except KeyboardInterrupt:
ret = '\x03'
finally:
# restore old state
termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
return ret
12 回答
简单地使用
将导致语法错误:解析时预期的EOF .
简单修复使用:
如果你想等待输入(因此用户敲击键盘不会导致无意中发生的事情)使用
我不知道采用独立于平台的方式,但在Windows下,如果使用msvcrt模块,则可以使用其getch函数:
mscvcrt还包括非阻塞kbhit()函数,用于查看是否按下键而不等待(不确定是否存在相应的curses函数) . 在UNIX下,有curses包,但不确定是否可以在不使用它的情况下使用它来进行所有屏幕输出 . 此代码适用于UNIX:
请注意,curses.getch()返回按下的键的序号,以使其具有我必须输出的相同输出 .
在Python 3中,不存在
raw_input()
. 所以,只需使用:这只等待用户按Enter键,因此您可能希望使用 msvcrt ((仅限Windows / DOS)msvcrt模块允许您访问Microsoft Visual C / C运行时库(MSVCRT)中的许多函数):
这应该等待按键 .
如果您可以依赖系统命令,则可以使用以下命令:
Linux的:
视窗:
如果你想看看他们是否按下了一个确切的键(比如说'b')这样做:
在Python 2中执行此操作的一种方法是使用
raw_input()
:在python3中它只是
input()
我是python的新手,我一直在想我太愚蠢了,无法重现这里提出的最简单的建议 . 事实证明,有一个应该知道的陷阱:
当从IDLE执行python脚本时,一些IO命令似乎表现完全不同(因为实际上没有终端窗口) .
例如 . msvcrt.getch是非阻塞的,总是返回$ ff . 这已经在很久以前就已经报道了(参见例如https://bugs.python.org/issue9290) - 并且它被标记为已修复,不知何故问题似乎在当前版本的python / IDLE中仍然存在 .
因此,如果上面发布的任何代码对您不起作用,请尝试手动运行脚本,并且 NOT from IDLE .
python manual提供以下内容:
这可以卷入你的用例 .
Cross Platform, Python 2/3 code:
我删除了fctl / non-blocking的东西,因为它给了
IOError
s并且我没有't need it. I' m使用这段代码,因为我希望它阻止 . ;)os.system似乎总是调用sh,它不识别读取的s和n选项 . 但是,read命令可以传递给bash:
在我的Linux机器上,我使用以下代码 . 这类似于其他地方提到的manual条目,但该代码在紧密循环中旋转,此代码不会解释此代码所做的事情 .