ein einzelnes Zeichen (getch Stil) in Python Lesen funktioniert nicht in Unix
Frage
Jedes Mal, wenn ich verwende das Rezept unter http://code.activestate.com/recipes/134892 / kann ich nicht scheinen, daran zu arbeiten. Es ist immer führt den folgenden Fehler:
Traceback (most recent call last):
...
old_settings = termios.tcgetattr(fd)
termios.error: (22, 'Invalid argument)
Mein bester Gedanke ist, dass es ist, weil ich es in Eclipse renne so ist termios
einen Sitz um den Dateideskriptor zu werfen.
Lösung
Dies funktioniert auf Ubuntu 8.04.1, Python 2.5.2, erhalte ich keinen solchen Fehler. Mai werden Sie es von der Kommandozeile versuchen sollte, eclipse seine eigene stdin verwenden kann, erhalte ich denselben Fehler genau, wenn ich es von Wing IDE laufen, aber von der Kommandozeile funktioniert es super. Grund ist, dass IDE z Flügel ist eine eigene Klasse netserver.CDbgInputStream als sys.stdin mit so sys.stdin.fileno ist Null, das ist, warum der Fehler. Grundsätzlich IDE stdin ist kein tty (Print sys.stdin.isatty () ist False)
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
getch = _GetchUnix()
print getch()
Andere Tipps
Putting-Terminal in Raw-Modus ist nicht immer eine gute Idee. Eigentlich ist es genug ICANON-Bit Bit zu löschen. Hier ist eine andere Version von getch () mit Timeout-Unterstützung:
import tty, sys, termios
import select
def setup_term(fd, when=termios.TCSAFLUSH):
mode = termios.tcgetattr(fd)
mode[tty.LFLAG] = mode[tty.LFLAG] & ~(termios.ECHO | termios.ICANON)
termios.tcsetattr(fd, when, mode)
def getch(timeout=None):
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
setup_term(fd)
try:
rw, wl, xl = select.select([fd], [], [], timeout)
except select.error:
return
if rw:
return sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
if __name__ == "__main__":
print getch()