703

我希望我的 python 脚本等到用户按下任何键。
我怎么做?

4

13 回答 13

714

Python 3中使用input()

input("Press Enter to continue...")

Python 2中使用raw_input()

raw_input("Press Enter to continue...")

这只等待用户按回车键。

可能需要使用msvcrt((仅限 Windows/DOS)msvcrt模块使您可以访问 Microsoft Visual C/C++ 运行时库 (MSVCRT) 中的许多函数):

import msvcrt as m
def wait():
    m.getch()

这应该等待按键。

附加信息:

在 Python 3raw_input()中不存在

在 Python 2input(prompt)中相当于eval(raw_input(prompt))

于 2009-07-16T01:48:20.217 回答
323

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

raw_input("Press Enter to continue...")

在python3中它只是input()

于 2009-06-11T20:11:59.177 回答
60

在我的 linux 机器上,我使用以下代码。这类似于我在其他地方看到的代码(例如在旧的 python 常见问题解答中),但是代码在一个紧密的循环中旋转,而这段代码没有,并且有很多奇怪的极端情况,代码没有考虑到这一点代码可以。

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)
于 2011-07-06T15:58:39.867 回答
40

如果您对取决于系统命令感到满意,则可以使用以下命令:

Linux 和 Mac OS X:

import os
os.system('read -s -n 1 -p "Press any key to continue..."')
print()

视窗:

import os
os.system("pause")
于 2013-06-05T06:36:48.553 回答
38

只需使用

input("Press Enter to continue...")

使用 Python 2 时会导致以下错误:

SyntaxError: 解析时预期的 EOF。

在 Python 2 和 Python 3 上工作的代码的简单修复是使用:

try:
    input("Press enter to continue")
except SyntaxError:
    pass
于 2014-03-03T16:06:30.717 回答
23

跨平台,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

我删除了 fctl/非阻塞的东西,因为它给了IOErrors 而我不需要它。我专门使用此代码是因为我希望它被阻止。;)

附录:

我在 PyPI 上的一个包中实现了这个,还有很多其他的东西叫做console

>>> from console.utils import wait_key

>>> wait_key()
'h'
于 2016-01-22T22:10:39.570 回答
19

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)

可以滚动到您的用例中。

于 2011-02-15T13:09:08.223 回答
14

我不知道独立于平台的方法,但是在 Windows 下,如果你使用 msvcrt 模块,你可以使用它的 getch 函数:

import msvcrt
c = msvcrt.getch()
print 'you entered', c

mscvcrt 还包括非阻塞 kbhit() 函数,以查看是否在没有等待的情况下按下了键(不确定是否有相应的 curses 函数)。在 UNIX 下,有 curses 包,但不确定是否可以在不将其用于所有屏幕输出的情况下使用它。此代码在 UNIX 下工作:

import curses
stdscr = curses.initscr()
c = stdscr.getch()
print 'you entered', chr(c)
curses.endwin()

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

于 2011-05-17T21:42:22.250 回答
4

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

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

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

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

于 2016-07-28T21:47:58.253 回答
4

如果您想等待输入(因此用户敲击键盘不会导致意外发生)使用

sys.stdin.readline()
于 2018-11-07T18:01:50.947 回答
1

os.system 似乎总是调用 sh,它不识别用于读取的 s 和 n 选项。但是可以将读取命令传递给 bash:

 os.system("""bash -c 'read -s -n 1 -p "Press any key to continue..."'""")
于 2013-12-18T06:39:33.047 回答
1

可以使用“键盘”库...

https://github.com/boppreh/keyboard#api

import keyboard
keyboard.wait('space')
print('space was pressed, continuing...')
于 2021-09-22T19:21:54.123 回答
-2

如果您想查看他们是否按下了确切的键(例如说“b”),请执行以下操作:

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break
于 2012-06-19T03:42:22.907 回答