Как заставить Python ждать нажатой клавиши - PullRequest
459 голосов
/ 12 июня 2009

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

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

Ответы [ 12 ]

410 голосов
/ 16 июля 2009

В Python 3 нет raw_input(). Так что просто используйте:

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

В Python 2 вы должны использовать raw_input(), так как input(prompt) эквивалентно eval(raw_input(prompt)):

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

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

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

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

314 голосов
/ 12 июня 2009

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

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

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

50 голосов
/ 06 июля 2011

В моей Linux-системе я использую следующий код. Это похоже на код, который я видел в другом месте (например, в старых FAQ по 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)
27 голосов
/ 05 июня 2013

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

Linux:

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

Windows

os.system("pause")
24 голосов
/ 03 марта 2014

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

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

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

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

try:
    input("Press enter to continue")
except SyntaxError:
    pass
14 голосов
/ 15 февраля 2011

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)

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

13 голосов
/ 18 мая 2011

Я не знаю, как это сделать независимо от платформы, но в 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 () возвращает порядковый номер нажатой клавиши, чтобы у нее был тот же вывод, что и для приведения.

12 голосов
/ 23 января 2016

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

2 голосов
/ 07 ноября 2018

Если вы хотите дождаться ввода (чтобы пользователь, стучащий по клавиатуре, не вызвал чего-то непредвиденного), используйте

sys.stdin.readline()
2 голосов
/ 29 июля 2016

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

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

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

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

...