Raw_input в python без нажатия enter

Я использую raw_input в Python для взаимодействия с пользователем в оболочке.

c = raw_input('Press s or n to continue:')
if c.upper() == 'S':
    print 'YES'

Он работает по назначению, но пользователь должен нажать enter в оболочке после нажатия 's'. Есть ли способ выполнить то, что мне нужно от пользовательского ввода, не требуя ввода ввода в оболочку? Я использую машины nixes.

Ответы

Ответ 1

В Windows вам понадобится модуль msvcrt, в частности, похоже, что вы описываете свою проблему, функцию msvcrt.getch

Прочтите нажатие клавиши и верните итоговый символ. Ничего не повторилось на консоль. Этот вызов блокирует если нажатие клавиши еще не доступно, но не будет ждать Enter для нажатия.

(и т.д. - см. документы, на которые я только что указал). Для Unix см., Например, этот рецепт для простого способа создания аналогичной функции getch (см. также несколько альтернатив & c в потоке комментариев этого рецепта).

Ответ 2

Python не предоставляет многоплатформенное решение из коробки.
Если вы находитесь в Windows, вы можете попробовать msvcrt с помощью:

import msvcrt
print 'Press s or n to continue:\n'
input_char = msvcrt.getch()
if input_char.upper() == 'S': 
   print 'YES'

Ответ 3

curses могут это сделать:

import curses, time

#--------------------------------------
def input_char(message):
    try:
        win = curses.initscr()
        win.addstr(0, 0, message)
        while True: 
            ch = win.getch()
            if ch in range(32, 127): break
            time.sleep(0.05)
    except: raise
    finally:
        curses.endwin()
    return chr(ch)
#--------------------------------------
c = input_char('Press s or n to continue:')
if c.upper() == 'S':
    print 'YES'

Ответ 4

Вместо модуля msvcrt вы также можете использовать WConio:

>>> import WConio
>>> ans = WConio.getkey()
>>> ans
'y'

Ответ 5

Чтобы получить один символ, я использовал getch, но я не знаю, работает ли он в Windows.

Ответ 6

С одной стороны, msvcrt.kbhit() возвращает логическое значение, определяющее, нажата ли в данный момент клавиша на клавиатуре.

Итак, если вы делаете игру или что-то еще и хотите, чтобы нажатия клавиш делали что-то, но не останавливали игру целиком, вы можете использовать kbhit() внутри оператора if, чтобы убедиться, что ключ извлекается только в том случае, если пользователь действительно хочет что-то делать.

Пример в Python 3:

# this would be in some kind of check_input function
if msvcrt.kbhit():
    key = msvcrt.getch().decode("utf-8").lower() # getch() returns bytes data that we need to decode in order to read properly. i also forced lowercase which is optional but recommended
    if key == "w": # here 'w' is used as an example
        # do stuff
    elif key == "a":
        # do other stuff
    elif key == "j":
        # you get the point

Ответ 7

Я знаю, что это старо, но решение не было достаточно хорошим для меня. Мне нужно решение для поддержки межплатформенных и без установки каких-либо внешних пакетов Python.

Мое решение для этого, на случай, если кто-нибудь еще наткнется на этот пост

Ссылка: https://github.com/unfor19/mg-tools/blob/master/mgtools/get_key_pressed.py

from tkinter import Tk, Frame


def __set_key(e, root):
    """
    e - event with attribute 'char', the released key
    """
    global key_pressed
    if e.char:
        key_pressed = e.char
        root.destroy()


def get_key(msg="Press any key ...", time_to_sleep=3):
    """
    msg - set to empty string if you don't want to print anything
    time_to_sleep - default 3 seconds
    """
    global key_pressed
    if msg:
        print(msg)
    key_pressed = None
    root = Tk()
    root.overrideredirect(True)
    frame = Frame(root, width=0, height=0)
    frame.bind("<KeyRelease>", lambda f: __set_key(f, root))
    frame.pack()
    root.focus_set()
    frame.focus_set()
    frame.focus_force()  # does not work in a while loop without it
    root.after(time_to_sleep * 1000, func=root.destroy)
    root.mainloop()
    root = None  # just in case
    return key_pressed


def __main():
        c = None
        while not c:
                c = get_key("Choose your weapon ... ", 2)
        print(c)

if __name__ == "__main__":
    __main()