我想在终端上获得输入,只需几秒钟即可回复。当达到超时时,我想读取作为给定输入的接受中输入的内容。或者我希望用户能够按“输入”提前提交答案。
我有下面的代码可以正常工作,但要求用户按“输入”提交。它有一个错误:输入文本然后等待超时将文本保留在“缓冲区”中。然后,当再次收到提示时,输入不同的文本,按Enter键,然后打印两个字符串(请参阅输出)。当达到超时时,我想接受任何被称为“答案”的内容。我希望用户仍然能够通过按“输入”更快地提交答案。
有没有办法达到预期的行为?
注意:我使用的是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
答案 0 :(得分: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键而不键入任何内容。如果时间用完,它会继续要求输入。我根本没有测试这个代码,我只是意识到它有很多局限性。
答案 1 :(得分:0)
这不是正常的控制台行为,但这里有一篇文章讨论了几个选项: