如何设置raw_input的时间限制

在python中,有没有办法在等待用户input时计算时间,以便在30秒之后自动跳过raw_input()函数?

基于@ jer推荐的解决scheme所基于的signal.alarm函数不幸的是只有Unix。 如果您需要跨平台或Windows特定的解决scheme,则可以将其基于threading.Timer,而使用thread.interrupt_main将KeyboardInterrupt从计时器线程发送到主线程。 即:

 import thread import threading def raw_input_with_timeout(prompt, timeout=30.0): print prompt, timer = threading.Timer(timeout, thread.interrupt_main) astring = None try: timer.start() astring = raw_input(prompt) except KeyboardInterrupt: pass timer.cancel() return astring 

这将返回None,无论是30秒超时还是用户明确决定打Ctrl-C放弃input任何东西,但似乎可以用相同的方式处理这两个case(如果你需要区分,你可以使用对于定时器来说,在中断主线程之前,定时器是一个函数,它logging了发生超时事件的地方,并且在你的KeyboardInterrupt访问处理程序中,“某处”区分出发生了哪种情况。

编辑 :我可以发誓这工作,但我一定是错了 – 上面的代码省略了明显需要的timer.start() ,甚至与它,我不能再工作了。 select.select是显而易见的其他尝试,但它不能在Windows中的“普通文件”(包括stdin)上运行 – 在Unix中它可以在所有文件上运行,在Windows中只运行在套接字上。

所以我不知道如何做一个跨平台的“超时input”。 一个特定于窗口的窗口可以使用严格循环轮询msvcrt.kbhit来构造,执行一个msvcrt.getche (并检查它是否是返回来指示输出已完成,在这种情况下,它将跳出循环,否则就会累积并保持等待)和检查时间,如果需要的话。 我不能testing,因为我没有Windows机器(他们都是Mac和Linux的),但在这里未经testing的代码,我会build议:

 import msvcrt import time def raw_input_with_timeout(prompt, timeout=30.0): print prompt, finishat = time.time() + timeout result = [] while True: if msvcrt.kbhit(): result.append(msvcrt.getche()) if result[-1] == '\r': # or \n, whatever Win returns;-) return ''.join(result) time.sleep(0.1) # just to yield to other processes/threads else: if time.time() > finishat: return None 

评论中的OP表示他不想在超时时return None ,但是另一种方法是什么? 引发exception? 返回一个不同的默认值? 无论他想要什么,他都可以清楚地把它代替我的return None ;-)。

如果你不想仅仅因为用户input缓慢而打出时间(而不是打字的话),你可以在每次成功的字符input之后重新计算finishat。

我在博客文章中find了解决这个问题的方法 。 以下是该博客的代码:

 import signal class AlarmException(Exception): pass def alarmHandler(signum, frame): raise AlarmException def nonBlockingRawInput(prompt='', timeout=20): signal.signal(signal.SIGALRM, alarmHandler) signal.alarm(timeout) try: text = raw_input(prompt) signal.alarm(0) return text except AlarmException: print '\nPrompt timeout. Continuing...' signal.signal(signal.SIGALRM, signal.SIG_IGN) return '' 

请注意: 此代码只能在* nix操作系统上运行

 from threading import Timer def input_with_timeout(x): def time_up(): answer= None print 'time up...' t = Timer(x,time_up) # x is amount of time in seconds t.start() try: answer = input("enter answer : ") except Exception: print 'pass\n' answer = None if answer != True: # it means if variable have somthing t.cancel() # time_up will not execute(so, no skip) input_with_timeout(5) # try this for five seconds 

因为它是自定义的…运行它在命令行提示符,我希望你会得到答案阅读这个python文档,你会清楚这个代码刚刚发生了什么!

input()函数devise为等待用户input内容(至less是[Enter]键)。

如果你没有设置使用input(),下面是使用tkinter更轻的解决scheme。 在tkinter中,对话框(和任何小部件)可以在给定的时间后被销毁。

这里是一个例子:

 import tkinter as tk def W_Input (label='Input dialog box', timeout=5000): w = tk.Tk() w.title(label) W_Input.data='' wFrame = tk.Frame(w, background="light yellow", padx=20, pady=20) wFrame.pack() wEntryBox = tk.Entry(wFrame, background="white", width=100) wEntryBox.focus_force() wEntryBox.pack() def fin(): W_Input.data = str(wEntryBox.get()) w.destroy() wSubmitButton = tk.Button(w, text='OK', command=fin, default='active') wSubmitButton.pack() # --- optionnal extra code in order to have a stroke on "Return" equivalent to a mouse click on the OK button def fin_R(event): fin() w.bind("<Return>", fin_R) # --- END extra code --- w.after(timeout, w.destroy) # This is the KEY INSTRUCTION that destroys the dialog box after the given timeout in millisecondsd w.mainloop() W_Input() # can be called with 2 parameter, the window title (string), and the timeout duration in miliseconds if W_Input.data : print('\nYou entered this : ', W_Input.data, end=2*'\n') else : print('\nNothing was entered \n') 

在linux下可以使用curses和getch函数,它的非阻塞性。 看getch()

https://docs.python.org/2/library/curses.html

函数等待键盘inputx秒(您必须首先初始化一个curses窗口(win1)!

 def tastaturabfrage(): einstiegszeit=int(time.time()) #get time now wartezeit=2.00 #time to wait in seconds while einstiegszeit+wartezeit>int(time.time()): key = win1.getch() #check if keyboard entry or screen resize if key == curses.KEY_RESIZE: empty() resize() key=0 if key == 118: p(4,'KEY V Pressed') yourfunction(); if key == 107: p(4,'KEY K Pressed') yourfunction(); if key == 99: p(4,'KEY c Pressed') yourfunction(); if key == 120: p(4,'KEY x Pressed') yourfunction(); else: yourfunction key=0 return 

一个需要进行定时math考试的诅咒例子

 #!/usr/bin/env python3 import curses import curses.ascii import time #stdscr = curses.initscr() - Using curses.wrapper instead def main(stdscr): hd = 100 #Timeout in tenths of a second answer = '' stdscr.addstr('5+3=') #Your prompt text s = time.time() #Timing function to show that solution is working properly while True: #curses.echo(False) curses.halfdelay(hd) start = time.time() c = stdscr.getch() if c == curses.ascii.NL: #Enter Press break elif c == -1: #Return on timer complete break elif c == curses.ascii.DEL: #Backspace key for corrections. Could add additional hooks for cursor movement answer = answer[:-1] y, x = curses.getsyx() stdscr.delch(y, x-1) elif curses.ascii.isdigit(c): #Filter because I only wanted digits accepted answer += chr(c) stdscr.addstr(chr(c)) hd -= int((time.time() - start) * 10) #Sets the new time on getch based on the time already used stdscr.addstr('\n') stdscr.addstr('Elapsed Time: %i\n'%(time.time() - s)) stdscr.addstr('This is the answer: %s\n'%answer) #stdscr.refresh() ##implied with the call to getch stdscr.addstr('Press any key to exit...') curses.wrapper(main)