我如何等待按下的按键?

2024-12-23 08:43:00
admin
原创
109
摘要:问题描述:如何让我的 Python 脚本等待直到用户按下任意键?解决方案 1:在Python 3中,使用input():input("Press Enter to continue...") 在Python 2中,使用raw_input():raw_input("Press En...

问题描述:

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


解决方案 1:

Python 3中,使用input()

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

Python 2中,使用raw_input()

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

但这仅等待用户按下回车键。


在 Windows/DOS 上,可能需要使用msvcrt。该msvcrt模块使您可以访问 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))

解决方案 2:

在 Python 3 中,使用input()

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

在 Python 2 中,使用raw_input()

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

解决方案 3:

在我的 Linux 机器上,我使用以下代码。这与我在其他地方看到的代码类似(例如在旧的 Python FAQ 中),但该代码在一个紧密的循环中旋转,而此代码不会,并且有很多奇怪的极端情况,代码没有考虑到,而此代码却考虑到了。

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)

解决方案 4:

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

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 兼容。

解决方案 5:

只需使用

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

使用Python2时会出现以下错误:

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

使代码在 Python 2 和 Python 3 上都能运行的简单修复方法是使用:

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

解决方案 6:

跨平台,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/non-blocking 内容,因为它给出了IOErrors 而我不需要它。我使用这个代码是因为我希望它阻塞。;)

附录:

我在 PyPI 上的一个包中实现了这个功能,其中还有许多其他名为console 的好东西:

>>> from console.utils import wait_key

>>> wait_key()
'h'

解决方案 7:

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)

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

解决方案 8:

我不知道是否有一种独立于平台的方法,但在 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()返回所按下键的序数,因此为了使其具有相同的输出,我必须对其进行转换。

解决方案 9:

我是 Python 新手,我已经认为自己太笨了,无法重现这里最简单的建议。事实证明,有一个陷阱需要知道:

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

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

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

解决方案 10:

您可以使用键盘库:

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

解决方案 11:

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

sys.stdin.readline()

解决方案 12:

os.system似乎总是调用sh,它无法识别 read 的 s 和 n 选项。但是 read 命令可以传递给 bash:

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

解决方案 13:

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

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1296  
  华为IPD产品开发流程是一套先进且成熟的产品开发管理体系,对众多企业提升产品竞争力有着重要的借鉴意义。它涵盖多个关键要素,这些要素相互关联、相互作用,共同构建起高效、科学的产品开发流程。深入剖析其中的五个核心要素,能让我们更好地理解华为成功背后的产品开发逻辑,为企业的产品创新与发展提供有力的指导。市场管理市场管理是IP...
IPD框架   6  
  华为集成产品开发(IPD)体系作为一套先进的产品开发管理理念和方法,在华为的发展历程中发挥了至关重要的作用。在供应链管理领域,IPD同样展现出巨大的价值,深刻影响着企业的运营效率、产品质量以及市场竞争力。通过将IPD理念融入供应链管理,华为实现了从产品规划到交付的全流程优化,为企业的持续发展奠定了坚实基础。IPD对供应...
IPD集成产品开发流程   6  
  IPD(Integrated Product Development)项目管理作为一种先进的产品开发管理模式,旨在通过整合跨部门资源,实现产品的高效开发与上市。然而,在实际推行过程中,IPD项目管理面临着诸多风险,若处理不当,可能导致项目进度延迟、成本超支甚至项目失败。深入了解这些风险并制定有效的应对策略,对于保障IP...
华为IPD流程   7  
  华为作为全球知名的科技企业,其成功背后的管理模式备受关注。其中,IPD(集成产品开发)产品开发流程对华为的创新发展起到了至关重要的推动作用。IPD不仅仅是一种流程,更是一种先进的管理理念,它将产品开发视为一个系统工程,涵盖了从市场需求分析、产品规划、研发、生产到上市等多个环节,通过整合企业内外部资源,实现高效、协同的产...
IPD流程中PDCP是什么意思   6  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用