你会如何提示用户输入一些信息但是在N秒后超时?
谷歌在http://mail.python.org/pipermail/python-list/2006-January/533215.html上指向了一个关于它的邮件线程,但似乎没有用.超时发生的语句,无论是sys.input.readline还是timer.sleep(),我总是得到:
:[raw_]输入最多需要1个参数,得2
以某种方式,除了没有抓住.
使用选择呼叫更短,并且应该更加便携
import sys, select print "You have ten seconds to answer!" i, o, e = select.select( [sys.stdin], [], [], 10 ) if (i): print "You said", sys.stdin.readline().strip() else: print "You said nothing!"
您链接到的示例是错误的,并且在调用警报处理程序而不是读取块时实际发生异常.最好试试这个:
import signal TIMEOUT = 5 # number of seconds your want for timeout def interrupted(signum, frame): "called when read times out" print 'interrupted!' signal.signal(signal.SIGALRM, interrupted) def input(): try: print 'You have 5 seconds to type in your stuff...' foo = raw_input() return foo except: # timeout return # set alarm signal.alarm(TIMEOUT) s = input() # disable the alarm after success signal.alarm(0) print 'You typed', s
不是Python解决方案,但......
我使用在CentOS(Linux)下运行的脚本来解决这个问题,对我的情况有用的只是在子进程中运行Bash"read -t"命令.我知道,野蛮恶心的黑客,但我对它的运作情况感到内疚,我想与大家分享.
import subprocess subprocess.call('read -t 30', shell=True)
除非按下ENTER键,否则我需要的是等待30秒的东西.这很有效.
这是一个适用于Windows的版本
我无法将这些示例中的任何一个用于Windows,因此我合并了一些不同的StackOverflow答案以获得以下内容:
import threading, msvcrt import sys def readInput(caption, default, timeout = 5): class KeyboardThread(threading.Thread): def run(self): self.timedout = False self.input = '' while True: if msvcrt.kbhit(): chr = msvcrt.getche() if ord(chr) == 13: break elif ord(chr) >= 32: self.input += chr if len(self.input) == 0 and self.timedout: break sys.stdout.write('%s(%s):'%(caption, default)); result = default it = KeyboardThread() it.start() it.join(timeout) it.timedout = True if len(it.input) > 0: # wait for rest of input it.join() result = it.input print '' # needed to move to next line return result # and some examples of usage ans = readInput('Please type a name', 'john') print 'The name is %s' % ans ans = readInput('Please enter a number', 10 ) print 'The number is %s' % ans
保罗的答案并不奏效.修改后的代码对我有用
Windows 7 x64
vanilla CMD shell(例如,不是 git-bash或其他非M $ shell)
- msvcrt
它出现在git-bash中没有任何作用.
python 3.6
(我发布了一个新的答案,因为直接编辑Paul的答案会改变它从python 2.x - > 3.x,这对编辑来说似乎太多了(py2仍在使用中)
import sys, time, msvcrt def readInput( caption, default, timeout = 5): start_time = time.time() sys.stdout.write('%s(%s):'%(caption, default)) sys.stdout.flush() input = '' while True: if msvcrt.kbhit(): byte_arr = msvcrt.getche() if ord(byte_arr) == 13: # enter_key break elif ord(byte_arr) >= 32: #space_char input += "".join(map(chr,byte_arr)) if len(input) == 0 and (time.time() - start_time) > timeout: print("timing out, using default value.") break print('') # needed to move to next line if len(input) > 0: return input else: return default # and some examples of usage ans = readInput('Please type a name', 'john') print( 'The name is %s' % ans) ans = readInput('Please enter a number', 10 ) print( 'The number is %s' % ans)