A small utility class to read single characters from standard input, on both Windows and UNIX systems. It provides a getch() function-like instance.
This extends the original script by adding a timeout necessary for another project.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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:
"""Fetch and character using the termios module."""
def __init__(self):
import tty, sys
from select import select
def __call__(self):
import sys, tty, termios
from select import select
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
# [ Wait until ready for reading,
# wait until ready for writing
# wait for an "exception condition" ]
# The below line times out after 1 second
# This can be changed to a floating-point value if necessary
[i, o, e] = select([sys.stdin.fileno()], [], [], 1)
if i:
ch = sys.stdin.read(1)
else:
ch = None
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
"""Fetch a character using the Microsoft Visual C Runtime."""
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
import time
# Delay timeout to match UNIX behaviour
time.sleep(1)
# Check if there is a character waiting, otherwise this would block
if msvcrt.kbhit():
return msvcrt.getch()
else:
return
getch = _Getch()
|
I forked this very useful script by Danny in order to include a timeout (I needed it to wait only a short time for input in a project and repeatedly check over a 10-second period before continuing on with the default option).