1

我想在终端上得到输入,只给几秒钟的时间来响应。当达到超时时,我想读取在接受中输入的任何内容作为给定的输入。可选地,我希望用户能够按“输入”以尽早提交他们的答案。

我有下面的代码可以正常工作,但需要用户按“输入”来提交。它有一个错误:输入文本然后等待超时将文本保留在“缓冲区”中。然后,当您再次收到提示时,您输入不同的文本,按回车键,然后打印两个字符串(见输出)。当达到超时时,我想接受输入的任何内容作为“答案”。我希望用户仍然能够通过按“输入”更快地提交答案。

有没有办法实现所需的行为?

注意:我使用的是 Mac OS X

import sys
from select import select

def getResponse(timeout):
   print "Enter something:"
   rlist, wlist, xlist = select([sys.stdin], [], [], timeout)
   if rlist:
      result = sys.stdin.readline()
      return result
   else:
      return ''

while True:
   response = getResponse(3)
   print "Your input is:", response

输出:

Enter something:
pythonYour input is: 
Enter something:
dangit
Your input is: pythondangit
4

2 回答 2

2

您希望以非阻塞方式从终端读取用户输入,并且还能够使读取超时,然后无需按 Enter 即可获取已写入的内容。至少这是有问题的,不会有一个简单的答案。作为起点,您可以考虑使用以下 ncurses 代码。用户最好不要删除他的输入!可以调整代码以处理字符删除和许多其他“花哨”功能,最终您可能会以迷你终端结束。

您所要求的通常是使用事件循环完成的,包括阅读部分(其中 raw_input 是一个糟糕的选择)。GUI 工具包可以更轻松、更健壮地解决这个问题(当然,它背后有几千行)。

import time
import curses

ENTER_KEY = (curses.KEY_ENTER, ord('\n'), ord('\r'))

def run(win, timeout=3): # timeout in seconds
    curses.echo()
    win.timeout(0) # Non-block read.

    line = 0
    while True:
        win.addstr(line, 0, "Enter something: ")
        s = []
        start = time.time()
        run = True
        while run:
            c = win.getch()
            time_taken = time.time() - start

            if c < 0:
                pass
            elif c in ENTER_KEY:
                break
            else:
                s.append(chr(c))

            if time_taken >= timeout:
                # Out of time.
                s.append(-1)
                run = False

        if len(s) == 0:
            break
        if s[-1] == -1:
            s.pop()
        answer = ''.join(s)
        win.addstr(line + 1, 0, "Your input was: %s" % answer)
        line += 2

curses.wrapper(run)

要优雅地结束,请按 Enter 键而不输入任何内容。如果时间用完,它会继续请求输入。我根本没有测试这段代码,我只是知道它有很多限制。

于 2013-01-14T04:01:35.357 回答
0

这不是正常的控制台行为,但这里有一篇讨论几个选项的帖子:

Python中超时的键盘输入

于 2013-01-14T01:52:47.453 回答