如何让python等待按下的键

Jan*_*usz 506 python wait keyboard-input

我希望我的脚本等到用户按任意键.

我怎么做?

riz*_*iza 462

在Python 3中,不raw_input()存在.所以,只需使用:

input("Press Enter to continue...")
Run Code Online (Sandbox Code Playgroud)

这只等待用户按Enter键,因此您可能需要使用msvcrt((仅限Windows/DOS)msvcrt模块允许您访问Microsoft Visual C/C++运行时库(MSVCRT)中的许多函数):

raw_input("Press Enter to continue...")
Run Code Online (Sandbox Code Playgroud)

这应该等待按键.

  • 当我尝试在Python 2.7中执行此操作时出现此错误:"SyntaxError:解析时意外的EOF" (52认同)
  • @JonTirsen那是因为Python 2.7有一个名为input的函数来评估你输入的字符串.要修复,请使用raw_input (13认同)
  • @ Solarsaturn9和越来越多的人没有.因此,这个答案对我和其他许多人来说都不起作用. (8认同)
  • @ Solarsaturn9再次阅读问题和回答:如果按下任何键,"输入"不会继续,仅当按下输入时才会继续. (6认同)
  • @richard使用input()也应该在其他平台上工作.当第一个解决方案是多平台解决方案时,为了提供替代Windows唯一解决方案而停靠点是荒谬的. (5认同)

Gre*_*ill 315

在Python 2中执行此操作的一种方法是使用raw_input():

raw_input("Press Enter to continue...")
Run Code Online (Sandbox Code Playgroud)

在python3中它只是 input()

  • [使用Python 3+](http://stackoverflow.com/questions/954834/easy-how-to-use-raw-input-in-3-1),这已改为`input()`. (33认同)
  • 什么时候它可以是多个键之一?不只是'输入'? (16认同)
  • http://stackoverflow.com/questions/1394956/how-to-do-hit-any-key-in-python (2认同)

mhe*_*man 53

在我的Linux机器上,我使用以下代码.这类似于其他地方提到的手动条目,但是代码在这个代码没有的紧密循环中旋转,并且有很多奇怪的角落情况,代码没有考虑到这个代码.

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 a tuple of characters of the key that was pressed - on Linux, 
    pressing keys like up arrow results in a sequence of characters. Returns 
    ('\x03',) 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
    ret = []
    try:
        ret.append(sys.stdin.read(1)) # returns a single character
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save | os.O_NONBLOCK)
        c = sys.stdin.read(1) # returns a single character
        while len(c) > 0:
            ret.append(c)
            c = sys.stdin.read(1)
    except KeyboardInterrupt:
        ret.append('\x03')
    finally:
        # restore old state
        termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
    return tuple(ret)
Run Code Online (Sandbox Code Playgroud)

  • @Mala,这在纯Python中几乎是不可能的;也许你应该写一个 C 模块? (2认同)

Cro*_*ouZ 28

如果您可以依赖系统命令,则可以使用以下命令:

Linux的:

os.system('read -s -n 1 -p "Press any key to continue..."')
print
Run Code Online (Sandbox Code Playgroud)

视窗:

os.system("pause")
Run Code Online (Sandbox Code Playgroud)


小智 28

简单地使用

input("Press Enter to continue...")
Run Code Online (Sandbox Code Playgroud)

将导致语法错误:解析时预期的EOF.

简单修复使用:

try:
    input("Press enter to continue")
except SyntaxError:
    pass
Run Code Online (Sandbox Code Playgroud)

  • 不要在python 2中使用`input` - 正确的函数是`raw_input`.在python 2中,`input`相当于`eval(raw_input())`. (5认同)
  • 另外,如果您要使用“输入”,则捕获 SyntaxError 是不合适的。无论用户键入什么,都会被评估,因此,例如,如果他们键入“1/0”,则会引发 ZeroDivisionError 而不是 SyntaxError,并且您的程序将退出。 (3认同)
  • 这将忽略用户按下的所有键,直到他们按下Enter键为止,这与OP要求的完全不同。 (2认同)

Jaa*_*egh 14

python 手册提供以下内容:

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
Run Code Online (Sandbox Code Playgroud)

这可以归结为您的用例.

  • 最好复制你正在链接的东西,以便知识保持不变,即使链接已经死亡(他们也会这样做!). (11认同)

Joh*_*Jr. 13

我不知道采用独立于平台的方式,但在Windows下,如果使用msvcrt模块,则可以使用其getch函数:

import msvcrt
c = msvcrt.getch()
print 'you entered', c
Run Code Online (Sandbox Code Playgroud)

mscvcrt还包括非阻塞kbhit()函数,用于查看是否按下键而不等待(不确定是否存在相应的curses函数).在UNIX下,有curses包,但不确定是否可以在不使用它的情况下使用它来进行所有屏幕输出.此代码适用于UNIX:

import curses
stdscr = curses.initscr()
c = stdscr.getch()
print 'you entered', chr(c)
curses.endwin()
Run Code Online (Sandbox Code Playgroud)

请注意,curses.getch()返回按下的键的序号,以使其具有我必须输出的相同输出.


Gri*_*ave 13

跨平台,Python 2/3代码:

# import sys, os

def wait_key():
    ''' Wait for a key press on the console and return it. '''
    result = None
    if os.name == 'nt':
        import msvcrt
        result = msvcrt.getch()
    else:
        import termios
        fd = sys.stdin.fileno()

        oldterm = termios.tcgetattr(fd)
        newattr = termios.tcgetattr(fd)
        newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
        termios.tcsetattr(fd, termios.TCSANOW, newattr)

        try:
            result = sys.stdin.read(1)
        except IOError:
            pass
        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

    return result
Run Code Online (Sandbox Code Playgroud)

我删除了fctl/non-blocking的东西,因为它给了IOErrors而我不需要它.我正在使用此代码,因为我希望它阻止.;)


ral*_*iii 5

我是Python新手,我已经在想我太愚蠢了,无法重现这里提出的最简单的建议。事实证明,有一个人们应该知道的陷阱:

当从 IDLE 执行 python 脚本时,某些 IO 命令的行为似乎完全不同(因为实际上没有终端窗口)。

例如。msvcrt.getch 是非阻塞的,并且始终返回 $ff。很久以前就已经报道过这个问题(参见https://bugs.python.org/issue9290) - 并且它被标记为已修复,不知怎的,这个问题似乎在当前版本的 python/IDLE 中仍然存在。

因此,如果上面发布的任何代码对您不起作用,请尝试手动运行脚本,而不是从 IDLE运行脚本。


w4d*_*325 5

您可以使用键盘库:

import keyboard
keyboard.wait('space')
print('space was pressed, continuing...')
Run Code Online (Sandbox Code Playgroud)

  • 在 Linux 中,这需要 root 权限。 (4认同)