阅读Python中的单个字符(残培风格)是不是在unix工作(Reading a single ch

2019-06-24 06:43发布

任何时候,我使用的配方在http://code.activestate.com/recipes/134892/我似乎无法得到它的工作。 它总是引发以下错误:

Traceback (most recent call last):
    ...
    old_settings = termios.tcgetattr(fd)
termios.error: (22, 'Invalid argument)

我最好的想法是,这是因为我在Eclipse中运行它这样termios是扔一个合适的有关文件的描述符。

Answer 1:

这是工作在Ubuntu 8.04.1,Python的2.5.2,我没有得到任何这样的错误。 可能是你应该尝试的命令行,偏食可以使用自己的标准输入,我得到完全相同的错误,如果我从永IDE运行它,而是从命令行它的伟大工程。 原因是IDE如翼使用有自己的类netserver.CDbgInputStream为sys.stdin所以sys.stdin.fileno是零,这就是为什么错误。 基本上IDE标准输入不是一个TTY(打印sys.stdin.isatty()为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()


Answer 2:

把终端进入原始模式并不总是一个好主意。 其实这足以清除ICANON位。 这里是残培()与超时支持的另一个版本:

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()


文章来源: Reading a single character (getch style) in Python is not working in Unix
标签: python getch