如何等待按键?

发布于 2024-07-24 18:41:34 字数 32 浏览 5 评论 0原文

如何让我的 python 脚本等待用户按下任意键?

How do I make my python script wait until the user presses any key?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

守不住的情 2024-07-31 18:41:34

Python 3中,使用input()

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

Python 2中,使用raw_input()

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

这只等待用户按下回车键。


在 Windows/DOS 上,人们可能想要使用 msvcrtmsvcrt 模块使您可以访问 Microsoft Visual C/C++ 运行时库 (MSVCRT) 中的许多函数:

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

这应该等待按键。


注意:

在 Python 3 中,raw_input() 不存在。
在 Python 2 中,input(prompt) 相当于 eval(raw_input(prompt))

In Python 3, use input():

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

In Python 2, use raw_input():

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

This only waits for the user to press enter though.


On Windows/DOS, one might want to use msvcrt. The msvcrt module gives you access to a number of functions in the Microsoft Visual C/C++ Runtime Library (MSVCRT):

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

This should wait for a key press.


Notes:

In Python 3, raw_input() does not exist.
In Python 2, input(prompt) is equivalent to eval(raw_input(prompt)).

梦在夏天 2024-07-31 18:41:34

在 Python 3 中,使用 input()

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

在 Python 2 中,使用 raw_input()

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

In Python 3, use input():

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

In Python 2, use raw_input():

raw_input("Press Enter to continue...")
孤寂小茶 2024-07-31 18:41:34

在我的 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)

On my linux box, I use the following code. This is similar to code I've seen elsewhere (in the old python FAQs for instance) but that code spins in a tight loop where this code doesn't and there are lots of odd corner cases that code doesn't account for that this code does.

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)
§对你不离不弃 2024-07-31 18:41:34

如果您同意依赖系统命令,您可以使用:

from __future__ import print_function
import os
import platform

if platform.system() == "Windows":
    os.system("pause")
else:
    os.system("/bin/bash -c 'read -s -n 1 -p \"Press any key to continue...\"'")
    print()

它已被验证可以在 Windows、Linux 和 Mac OS X 上与 Python 2 和 3 一起使用。

If you are ok with depending on system commands you can use:

from __future__ import print_function
import os
import platform

if platform.system() == "Windows":
    os.system("pause")
else:
    os.system("/bin/bash -c 'read -s -n 1 -p \"Press any key to continue...\"'")
    print()

It has been verified to work with Python 2 and 3 on Windows, Linux and Mac OS X.

心舞飞扬 2024-07-31 18:41:34

简单地

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

使用Python 2时会出现以下错误:

语法错误:解析时预期出现 EOF。

要使代码在 Python 2 和 Python 3 上都能工作,简单的修复方法是使用:

try:
    input("Press enter to continue")
except SyntaxError:
    pass

Simply using

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

will cause the following error when using Python 2:

SyntaxError: expected EOF while parsing.

Simple fix for the code to work on both Python 2 and Python 3 is to use:

try:
    input("Press enter to continue")
except SyntaxError:
    pass
韶华倾负 2024-07-31 18:41:34

跨平台,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.getwch()
    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 上的一个包中实现了这个,还有很多其他的好东西,称为 控制台:

>>> from console.utils import wait_key

>>> wait_key()
'h'

Cross Platform, Python 2/3 code:

# 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.getwch()
    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

I removed the fctl/non-blocking stuff because it was giving IOErrors and I didn't need it. I'm using this code specifically because I want it to block. ;)

Addendum:

I implemented this in a package on PyPI with a lot of other goodies called console:

>>> from console.utils import wait_key

>>> wait_key()
'h'
雪化雨蝶 2024-07-31 18:41:34

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)

可以将其纳入您的用例中。

The python manual provides the following:

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)

which can be rolled into your use case.

无可置疑 2024-07-31 18:41:34

我不知道独立于平台的方法,但是在 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() 返回按下的键的序号,以便使其具有与我必须强制转换它相同的输出。

I don't know of a platform independent way of doing it, but under Windows, if you use the msvcrt module, you can use its getch function:

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

mscvcrt also includes the non-blocking kbhit() function to see if a key was pressed without waiting (not sure if there's a corresponding curses function). Under UNIX, there is the curses package, but not sure if you can use it without using it for all of the screen output. This code works under UNIX:

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

Note that curses.getch() returns the ordinal of the key pressed so to make it have the same output I had to cast it.

挽清梦 2024-07-31 18:41:34

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

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

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

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

I am new to python and I was already thinking I am too stupid to reproduce the simplest suggestions made here.
It turns out, there's a pitfall one should know:

When a python-script is executed from IDLE, some IO-commands seem to behave completely different (as there is actually no terminal window).

Eg. msvcrt.getch is non-blocking and always returns $ff.
This has already been reported long ago (see e.g. https://bugs.python.org/issue9290 ) - and it's marked as fixed, somehow the problem seems to persist in current versions of python/IDLE.

So if any of the code posted above doesn't work for you, try running the script manually, and NOT from IDLE.

梦一生花开无言 2024-07-31 18:41:34

您可以使用 键盘 库:

import keyboard
keyboard.wait('space')
print('space was pressed, continuing...')

You could use the keyboard library:

import keyboard
keyboard.wait('space')
print('space was pressed, continuing...')
絕版丫頭 2024-07-31 18:41:34

如果你想等待输入(这样用户敲击键盘就不会导致意外的事情发生)使用

sys.stdin.readline()

If you want to wait for enter (so the user knocking the keyboard does not cause something un-intended to happen) use

sys.stdin.readline()
地狱即天堂 2024-07-31 18:41:34

os.system 似乎总是调用 sh ,它无法识别 s 和 n 选项进行读取。 然而,读取命令可以传递给 bash:

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

os.system seems to always invoke sh, which does not recognize the s and n options for read. However the read command can be passed to bash:

os.system("""bash -c 'read -s -n 1 -p "Press any key to continue..."'""")
用心笑 2024-07-31 18:41:34

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

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break

If you want to see if they pressed a exact key (like say 'b') Do this:

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文