2013-03-20 75 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