Вопрос-Ответ

How to read a single character from the user?

Как прочитать один символ от пользователя?

Есть ли способ прочитать один символ из пользовательского ввода? Например, они нажимают одну клавишу на терминале, и она возвращается (что-то вроде getch()). Я знаю, что в Windows есть функция для этого, но я бы хотел что-то кроссплатформенное.

Переведено автоматически
Ответ 1

Вот ссылка на сайт рецептов ActiveState, на котором рассказывается, как вы можете прочитать один символ в Windows, Linux и OSX:

    getch() - как небуферизованное чтение символов из stdin как в Windows, так и в Unix

class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""

def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()

def __call__(self): return self.impl()


class _GetchUnix:
def __init__(self):
import tty, sys

def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch


class _GetchWindows:
def __init__(self):
import msvcrt

def __call__(self):
import msvcrt
return msvcrt.getch()


getch = _Getch()
Ответ 2
sys.stdin.read(1)

в основном считывает 1 байт из STDIN.

Если вам необходимо использовать метод, который не ожидает \n вы можете использовать этот код, как было предложено в предыдущем ответе:

class _Getch:
"""Gets a single character from standard input. Does not echo to the screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()

def __call__(self): return self.impl()


class _GetchUnix:
def __init__(self):
import tty, sys

def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch


class _GetchWindows:
def __init__(self):
import msvcrt

def __call__(self):
import msvcrt
return msvcrt.getch()


getch = _Getch()

(взято из http://code.activestate.com/recipes/134892 / )

Ответ 3

Стоит попробовать библиотеку readchar, которая частично основана на рецепте ActiveState, упомянутом в других ответах (но с тех пор прошла долгий путь).

Установка:

python -m pip install readchar

Использование:

import readchar
print('Reading a char:')
print(repr(readchar.readchar()))
print('Reading a key:')
print(repr(readchar.readkey()))

Это было протестировано в Windows и Linux с помощью Python 3.9. Это также должно работать в терминале PyCharm.

Коды ключей не всегда одинаковы в Windows и Linux, но библиотека предоставляет определения для конкретной платформы, такие как readchar.key.F1, чтобы помочь в этом.

Поскольку Linux сообщает большинство специальных ключей как escape-последовательности (начинающиеся с \x1b), readkey() возникает путаница, если вы нажимаете фактическую Escape-клавишу (сообщаемую терминалом как одиночную \x1b). К сожалению, это распространенная проблема Unix, не имеющая по-настоящему надежного решения.

Обратите внимание, что при readkey повышении KeyboardInterrupt на Ctrl+C (см. readchar.config) другие сигнальные ключи Linux (например, Ctrl+D и Ctrl+Z) перехватываются и возвращаются (как '\x04' и '\x1a' соответственно), что может быть желательным, а может и не быть.

Для получения функциональности в виде приглашения ввода, аналогичной функциональности Python, input()рассмотрите этот вопрос.

Ответ 4

Рецепт ActiveState, дословно приведенный в двух ответах, переработан. Его можно свести к следующему:

def _find_getch():
try:
import termios
except ImportError:
# Non-POSIX. Return msvcrt's (Windows') getch.
import msvcrt
return msvcrt.getch

# POSIX system. Create and return a getch that manipulates the tty.
import sys, tty
def _getch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch

return _getch

getch = _find_getch()
python