Рецепт ActiveState, кажется, содержит небольшую ошибку для "posix" систем, которая предотвращает прерывание Ctrl-C
(я использую Mac). Если я добавлю следующий код в мой скрипт:
while(True):
print(getch())
Я никогда не смогу завершить сценарий с помощью Ctrl-C
, и мне нужно убить свой терминал, чтобы сбежать.
Я считаю, что следующая строка является причиной, и она также слишком жестока:
tty.setraw(sys.stdin.fileno())
Кроме того, пакет tty
на самом деле не нужен, для его обработки достаточно termios
.
Ниже приведен улучшенный код, который работает для меня (Ctrl-C
будет прерывать), с дополнительной функцией getche
, которая отображает символ при вводе:
if sys.platform == 'win32':
import msvcrt
getch = msvcrt.getch
getche = msvcrt.getche
else:
import sys
import termios
def __gen_ch_getter(echo):
def __fun():
fd = sys.stdin.fileno()
oldattr = termios.tcgetattr(fd)
newattr = oldattr[:]
try:
if echo:
# disable ctrl character printing, otherwise, backspace will be printed as "^?"
lflag = ~(termios.ICANON | termios.ECHOCTL)
else:
lflag = ~(termios.ICANON | termios.ECHO)
newattr[3] &= lflag
termios.tcsetattr(fd, termios.TCSADRAIN, newattr)
ch = sys.stdin.read(1)
if echo and ord(ch) == 127: # backspace
# emulate backspace erasing
# https://stackoverflow.com/a/47962872/404271
sys.stdout.write('\b \b')
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, oldattr)
return ch
return __fun
getch = __gen_ch_getter(False)
getche = __gen_ch_getter(True)
Ссылки: