【问题标题】:Python STDIN User Input IssuePython STDIN 用户输入问题
【发布时间】:2016-01-26 16:02:54
【问题描述】:

问题

执行这两个函数时与 STDIN 冲突。什么会导致第二个函数无法正确读取 STDIN?如果第一个函数未执行,则第二个函数读取输入没有问题。

我尝试过清除 STDIN 缓冲区:

'sys.stdin.flush'

'tcflush(sys.stdin, TCIOFLUSH)'

Python 代码

import sys, select

def stdin_read():

    print "[stdin read] You must answer Y/N and press ENTER"
    sys.stdout.flush()
    response = sys.stdin.read(1)
    print "You said '{}'".format(response)


def stdin_timeout():

    print "[stdin timeout] You must answer YES / NO in 10 seconds and press ENTER"
    sys.stdout.flush()

    sys.stdin.flush()

    i, o, e = select.select( [sys.stdin], [], [], 10 )

    if (i):
        print "You said '{}'".format(sys.stdin.readline().strip())
        exit(0)
    else:
        print "You said nothing!"
        exit(1)


stdin_read()
stdin_timeout()

Python 输出两个函数:

:~# python input.py
[stdin read] You must answer Y/N and press ENTER
n
You said 'n'
[stdin timeout] You must answer YES / NO in 10 seconds and press ENTER
no
You said ''
:~# no
-bash: no: command not found

Python 输出第二个函数

~# python input.py
[stdin timeout] You must answer YES / NO in 10 seconds and press ENTER
no
You said 'no'

【问题讨论】:

    标签: python input stdin


    【解决方案1】:

    问题出自the behaviour of stdin flushing in unix

    我将通过评论您的代码来回答:

    import sys, select
    
    def stdin_read():
    
        print "[stdin read] You must answer Y/N and press ENTER"
        # sys.stdout.flush() # not needed
        # you are reading one byte here, but the user enters at least two bytes
        # (e.g 'y' + LF(enter key)) so the LF byte (and possibly additional bytes)
        # remain in the stdin buffer.
        response = sys.stdin.read(1) # (->LF REMAINS)
        print "You said '{}'".format(response)
    
    
    def stdin_timeout():
    
        print "[stdin timeout] You must answer YES / NO in 10 seconds and press ENTER"
        #sys.stdout.flush() #  not needed
        # the behaviour of stdin flushing in unix is not defined (see 
        # link above)
        sys.stdin.flush()
        # thus the LF still remains in the stdin buffer
    
        # the select call blocks until the file discriptor is 'ready' for
        # the corresponding i/o operation. DISCLAIMER: assumptions are
        # following.... By default python does a open call which uses
        # buffered reads, so even if you did a read(1) it will likely read
        # more data from stdin and the select call blocks until the next LF
        # arrives.
        i, o, e = select.select( [sys.stdin], [], [], 10 )
    
        if (i):
            # you are just reading the left over bytes from above (->LF REMAINS)
            print "You said '{}'".format(sys.stdin.readline().strip())
            # Proof: readline() again:
            print "You missed '{}'".format(sys.stdin.readline().strip())
            exit(0)
        else:
            print "You said nothing!"
            exit(1)
    
    
    stdin_read()
    stdin_timeout()
    

    但也许使用另一种方法会更好Keyboard input with timeout in Python

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      相关资源
      最近更新 更多