قراءة حرف واحد (نمط getch) في بيثون لا يعمل في يونكس
سؤال
وأي وقت يمكنني استخدام وصفة في http://code.activestate.com/recipes/134892 / أنا لا يمكن أن يبدو للحصول على عمل. كان دائما يلقي الخطأ التالي:
Traceback (most recent call last):
...
old_settings = termios.tcgetattr(fd)
termios.error: (22, 'Invalid argument)
وأفضل فكرتي هي أن يكون ذلك بسبب أنا على التوالي في الكسوف حتى termios
هو رمي نوبة حول واصف الملف.
المحلول
وهذا يعمل على أوبونتو 8.04.1، بايثون 2.5.2، أحصل على أي خطأ من هذا القبيل. قد يكون عليك أن تحاول ذلك من سطر الأوامر، كسوف قد تستخدم ستدين الخاصة به، وأحصل على نفس بالضبط الخطأ إذا كنت تشغيله من الجناح IDE، ولكن من سطر الأوامر يعمل كبيرة. السبب هو أن IDE منها مثلا الجناح تستخدم هناك netserver.CDbgInputStream الدرجة الخاصة كما sys.stdin حتى sys.stdin.fileno هو صفر، ولهذا السبب الخطأ. في الأساس IDE ستدين ليس الكتابة البعيدة (sys.stdin.isatty الطباعة () غير صحيح)
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()
نصائح أخرى
ووضع محطة في وضع الخام ليست دائما فكرة جيدة. في الواقع يكفي لمسح ICANON قليلا. هنا هو نسخة أخرى من getch () مع دعم المهلة:
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()