【问题标题】:How do I read user input as it is being typed?如何在输入时读取用户输入?
【发布时间】:2017-03-09 09:02:58
【问题描述】:

我想知道如何让 Python 在输入输入时验证输入行并使用输入完成任务。 例如:

alphabet = "abcdefghijklmnopqrstuvwxyz"

useralphabet = input("Please enter however much of the alphabet you know:")

while(useralphabet in alphabet):
    break

print("You know", 26 - len(useralphabet), "letters of the alphabet!")

显然我知道这段代码不会按预期工作,但我希望它展示了我正在尝试做的事情的想法,即让用户输入文本,直到他们输入的文本不再是指定的字符串。

【问题讨论】:

标签: python input


【解决方案1】:

答案取决于您的操作系统(操作系统)。通常,只有在您按下ENTER 键后,操作系统才会将输入字符串交给 python。如果您需要在键入时执行此操作,则可能需要调用一些系统相关调用来关闭输入缓冲。

有关更多信息,请参阅Python read a single character from the user

【讨论】:

    【解决方案2】:

    这是一个工作示例(在 Linux 上使用 Python 3.8.6 测试)。其他系统需要修改请看this回答。

    hinput 函数在输入字符时读取它们,并为每个新字符调用on_char,同时传递新字符和整行。

    在我的示例中,当用户键入 x 时,on_char 函数会返回 True,这会导致 hinput 函数停止等待新输入。

    如果用户输入hello,它会自动补全为hello, world,同时也会终止hinput

    import sys
    import termios
    import tty
    from typing import Callable
    
    def main():
        hinput("prompt: ", on_char)
        return 0
    
    def on_char(ch: str, line: str) -> bool:
        if ch == 'x':
            sys.stdout.write('\n')
            sys.stdout.flush()
            return True
        if line+ch == 'hello':
            sys.stdout.write("%s, world\n" % ch)
            sys.stdout.flush()
            return True
        return False
    
    def hinput(prompt: str=None, hook: Callable[[str,str], bool]=None) -> str:
        """input with a hook for char-by-char processing."""
        fd = sys.stdin.fileno()
        old = termios.tcgetattr(fd)
        inpt = ""
        while True:
            sys.stdout.write('\r')
            if prompt is not None:
                sys.stdout.write(prompt)
            sys.stdout.write(inpt)
            sys.stdout.flush()
                
            ch = None
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(fd, termios.TCSADRAIN, old)
    
            if hook is not None and hook(ch, inpt):
                break
    
            if ord(ch) == 0x7f: #BACKSPACE
                if len(inpt) > 0:
                    sys.stdout.write('\b \b')
                    inpt = inpt[:-1]
                continue
    
            if ord(ch) == 0x0d: #ENTER
                sys.stdout.write('\n')
                sys.stdout.flush()
                break
    
            if ch.isprintable():
                inpt += ch
                
        return inpt
    
    if __name__ == '__main__':
        sys.exit(main())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 2019-01-10
      相关资源
      最近更新 更多