2013-03-20 59 views
5

我希望能做的是使用输入问一个用户一个问题。例如:Python 3定时输入

print('some scenario') 
prompt = input("You have 10 seconds to choose the correct answer...\n") 

,然后如果时间流逝打印像

print('Sorry, times up.') 

任何指着我的方向是正确的帮助将不胜感激。

+0

@interjay我已经发布我的问题之前,先阅读张贴。首先,我在一个不是Unix的Windows平台上。被接受的答案是只有Unix,我相信后来回答的人说它甚至没有工作。另外我正在使用Python 3.我需要使用input而不是raw_input。 – cloud311 2013-03-20 16:47:39

+3

关于这个问题和Francesco Frassinelli发布的问题有多个答案,其中许多答案不是unix专有的。你可以简单地把'raw_input'改成'input'。顺便提一下,当您提出问题时,您应该指定相关信息,例如在Windows上运行,以及您尝试过但未运行的解决方案,以免人们浪费时间重写旧的答案。 – interjay 2013-03-20 16:52:11

+1

[在Python中输入超时的键盘](http://stackoverflow.com/q/1335507/4279) – jfs 2014-10-20 02:45:20

回答

3

有趣的问题,这似乎工作:

import time 
from threading import Thread 

answer = None 

def check(): 
    time.sleep(2) 
    if answer != None: 
     return 
    print "Too Slow" 

Thread(target = check).start() 

answer = raw_input("Input something: ") 
+3

你可以[使用'threading.Timer'而不是'Thread' +'time.sleep'](http://stackoverflow.com/a/15533404/4279)。 Python 3中没有'raw_input'。 – jfs 2013-03-20 20:08:18

+3

raw_input()在mainthread中如何终止?我看到线程检查()结束并将“太慢”推送到标准输出。但不是raw_input()如何获得stdin缓冲区填充或“完成”。 – DevPlayer 2016-09-15 13:08:44

8

如果可以接受阻塞主线程,当用户没有提供一个答案:

from threading import Timer 

timeout = 10 
t = Timer(timeout, print, ['Sorry, times up']) 
t.start() 
prompt = "You have %d seconds to choose the correct answer...\n" % timeout 
answer = input(prompt) 
t.cancel() 

否则,你可以使用@Alex Martelli's answer (修改为Python 3)在Windows(未测试):

import msvcrt 
import time 

class TimeoutExpired(Exception): 
    pass 

def input_with_timeout(prompt, timeout, timer=time.monotonic): 
    sys.stdout.write(prompt) 
    sys.stdout.flush() 
    endtime = timer() + timeout 
    result = [] 
    while timer() < endtime: 
     if msvcrt.kbhit(): 
      result.append(msvcrt.getwche()) #XXX can it block on multibyte characters? 
      if result[-1] == '\n': #XXX check what Windows returns here 
       return ''.join(result[:-1]) 
     time.sleep(0.04) # just to yield to other processes/threads 
    raise TimeoutExpired 

用法:

try: 
    answer = input_with_timeout(prompt, 10) 
except TimeoutExpired: 
    print('Sorry, times up') 
else: 
    print('Got %r' % answer) 

在Unix上你可以尝试:

import select 
import sys 

def input_with_timeout(prompt, timeout): 
    sys.stdout.write(prompt) 
    sys.stdout.flush() 
    ready, _, _ = select.select([sys.stdin], [],[], timeout) 
    if ready: 
     return sys.stdin.readline().rstrip('\n') # expect stdin to be line-buffered 
    raise TimeoutExpired 

或者:

import signal 

def alarm_handler(signum, frame): 
    raise TimeoutExpired 

def input_with_timeout(prompt, timeout): 
    # set signal handler 
    signal.signal(signal.SIGALRM, alarm_handler) 
    signal.alarm(timeout) # produce SIGALRM in `timeout` seconds 

    try: 
     return input(prompt) 
    finally: 
     signal.alarm(0) # cancel alarm 
+1

第一个答案在超时后打印,但输入仍然可用。 – 2016-07-12 22:57:07

+1

@EliezerMiron:是的,在第一个例子中'input()'调用没有被中断,这就是为什么在这个例子之前有*:“如果阻塞主线程是可以接受的”。如果需要插入输入,请使用'input_with_timeout()'的以下示例。 – jfs 2016-09-30 20:00:24

+0

我试过使用'import signal',它的时间感似乎没有了。我正在使用Cloud9 IDE。如果我给它一个.5超时,它会在超时之前等待约3秒钟。 – 2017-02-03 05:16:00