Как заставить python ждать нажатой клавиши

Я хочу, чтобы мой скрипт ждал, пока пользователь не нажмет любую клавишу.

Как мне это сделать?

11 ответов


в Python 3, нет . Итак, просто используйте:

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

Это только ждет, пока пользователь нажмет enter, поэтому вы можете использовать msvcrt ((только для Windows/DOS) модуль msvcrt предоставляет доступ к ряду функций в библиотеке Microsoft Visual C/C++ Runtime Library (MSVCRT)):

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

Это должно ждать нажатия клавиши.


один из способов сделать это в Python 2, это использовать raw_input():

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

в python3 это просто input()


в моем поле 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 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

Если вы в порядке в зависимости от системных команд, вы можете использовать следующее:

Linux:

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

окна:

os.system("pause")

просто используя

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

вызовет SyntaxError: ожидаемый EOF во время синтаксического анализа.

простое использование исправления:

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

питон руководство предусматривает следующее:

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)

который можно свернуть в ваш вариант использования.


Я не знаю независимого от платформы способа сделать это, но под Windows, Если вы используете модуль msvcrt, вы можете использовать его функцию getch:

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

mscvcrt также включает неблокирующую функцию kbhit (), чтобы увидеть, была ли нажата клавиша без ожидания (не уверен, есть ли соответствующая функция проклятий). В UNIX есть пакет curses, но не уверен, что вы можете использовать его, не используя его для всех выходных данных экрана. Этот код работает под В Unix:

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

обратите внимание, что проклятия.getch () возвращает порядковый номер клавиши, нажатой так, чтобы он имел тот же вывод, который я должен был бросить.


кросс-платформа, код 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, и мне это не нужно. Я использую этот код специально, потому что хочу его заблокировать. ;)


Я новичок в python, и я уже думал, что я слишком глуп, чтобы воспроизвести самые простые предложения, сделанные здесь. Оказывается, есть ловушка, которую нужно знать:

когда python-скрипт выполняется из IDLE, некоторые IO-команды, похоже, ведут себя совершенно иначе (поскольку на самом деле нет окна терминала).

например. библиотеки msvcrt.getch не блокирует и всегда возвращает $ff. Об этом уже давно сообщалось (см. https://bugs.python.org/issue9290) - и он отмечен как фиксированный, каким-то образом проблема, похоже, сохраняется в текущих версиях python/IDLE.

поэтому, если какой-либо из вышеперечисленных кодов не работает для вас, попробуйте запустить скрипт вручную и не от простоя.


Если вы хотите увидеть, нажали ли они точную клавишу (например, "b"), сделайте следующее:

while True:
    choice = raw_input("> ")

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

os.система, похоже, всегда вызывает sh, который не распознает параметры S и n для чтения. Однако команда read может быть передана bash:

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