Python 2.7 键盘输入超时,不按enter键

Python 2.7 键盘输入超时,不按enter键,python-2.7,input,timeout,Python 2.7,Input,Timeout,我正在用Python编写一个程序,在我的Raspberry Pi上运行。很多人都知道,覆盆子可以接受多种输入方式。我正在使用键盘和另一个外部输入源。这只是为了语境化,对问题本身并不重要 在我的程序中,我等待键盘输入,如果在短时间内没有键盘输入,我会跳过并查找其他来源的输入。为此,我使用以下代码: import sys import time from select import select timeout = 4 prompt = "Type any number from 0 up t

我正在用Python编写一个程序,在我的Raspberry Pi上运行。很多人都知道,覆盆子可以接受多种输入方式。我正在使用键盘和另一个外部输入源。这只是为了语境化,对问题本身并不重要

在我的程序中,我等待键盘输入,如果在短时间内没有键盘输入,我会跳过并查找其他来源的输入。为此,我使用以下代码:

import sys
import time
from select import select

timeout = 4  
prompt = "Type any number from 0 up to 9"
default = 99 

def input_with(prompt, timeout, default):
    """Read an input from the user or timeout"""
    print prompt,
    sys.stdout.flush()
    rlist, _, _ = select([sys.stdin], [], [], timeout)
    if rlist:
        s = int(sys.stdin.read().replace('\n',''))
    else:
        s = default
        print s
    return s
我将在没有完整键盘的情况下运行Raspberry Pi,这意味着我没有返回键。以这种方式验证键盘输入是不可能的

我怀疑是否有可能在不按enter键并保持输入超时的情况下获取用户输入

我看到很多话题都在讨论这两个问题(超时和输入,但不按return),但都没有讨论


提前感谢您的帮助

我不认为按照您想要的方式来做是很简单的,即读取线上等待的内容,即使没有按enter键(对吗?)

我能提供的最好建议是,在按下每个字符时捕获它,并在时间过去后调用。您可以通过设置cbreak模式来捕获每个字符的输入:
tty.setcbreak()


这是一个有趣的问题
stdin
不是这样工作的,它是逐行的。您必须考虑以某种方式直接捕获tty。想想当你在登录时输入密码时,它是如何绕过stdin的。。它是从到
time。time()
可以向后设置。您可能还应该允许
eof
eol
字符终止输入(除了
b'\n'
)--请参见
stty-a
。谢谢,我不确定您所说的
time.time
是什么意思。这是否意味着出于这个原因它是不可靠的?我不相信EOL是关于树莓皮的问题。在非*nix平台上,您可能会支持它,但它可能会被完全忽略。。使用
Ctrl+D
(eof)尝试您的代码。我在评论中提到的
eol
与Windows无关。看见
import sys
from select import select
import tty
import termios

try:
    # more correct to use monotonic time where available ...
    from time33 import clock_gettime
    def time(): return clock_gettime(0)
except ImportError:
    # ... but plain old 'time' may be good enough if not.
    from time import time

timeout = 4  
prompt = "Type any number from 0 up to 9"
default = 99 

def input_with(prompt, timeout, default):
    """Read an input from the user or timeout"""
    print prompt,
    sys.stdout.flush()

    # store terminal settings
    old_settings = termios.tcgetattr(sys.stdin)

    buff = ''
    try:    
        tty.setcbreak(sys.stdin) # flush per-character

        break_time = time() + timeout

        while True:

            rlist, _, _ = select([sys.stdin], [], [], break_time - time())
            if rlist:
                c = sys.stdin.read(1)

                # swallow CR (in case running on Windows)
                if c == '\r':
                    continue
                # newline EOL or EOF are also end of input
                if c in ('\n', None, '\x04'):
                    break # newline is also end of input
                buff += c

                sys.stdout.write(c) # echo back
                sys.stdout.flush()

            else: # must have timed out
                break

    finally:
        # put terminal back the way it was
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings)

    if buff:
        return int(buff.replace('\n','').strip())
    else:
        sys.stdout.write('%d' % default)
        return default