How to set time limit on raw_input
在python中,在等待用户输入时,是否有方法计算时间,以便在30秒后自动跳过
不幸的是,@jer推荐的解决方案所基于的signal.alarm函数只是unix。如果需要跨平台或特定于Windows的解决方案,可以基于threading.timer,而使用thread.interrupt_main从计时器线程向主线程发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 |
无论是30秒超时还是用户明确决定点击control-c放弃输入任何内容,这都不会返回任何结果,但以同样的方式处理这两种情况似乎是可以的(如果需要区分,您可以为计时器使用自己的函数,在中断主线程之前,在某个地方记录一个事实,即超时已经发生了,在您的
编辑:我可以发誓这是可行的,但我一定是错了——上面的代码省略了明显需要的
所以我不知道如何做一个跨平台的"原始输入超时"。一个特定于Windows的系统可以通过一个紧密的循环轮询msvcrt.kbhit来构造,执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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] == ' ': # or , whatever Win returns;-) return ''.join(result) time.sleep(0.1) # just to yield to other processes/threads else: if time.time() > finishat: return None |
在一条评论中的操作人员说,他不想在超时时使用
如果你不想因为用户打字慢而超时(相反,根本不想打字!-,您可以在每次成功输入字符后重新计算finishinat。
我在一篇博文中找到了解决这个问题的方法。这是那篇博文的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 ' Prompt timeout. Continuing...' signal.signal(signal.SIGALRM, signal.SIG_IGN) return '' |
请注意:此代码仅适用于*nix oss。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 ' 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()函数用于等待用户输入内容(至少是[enter]键)。
如果您没有设置为使用input(),下面是一个使用tkinter的更轻的解决方案。在Tkinter中,对话框(和任何小部件)可以在给定时间后销毁。
下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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(' You entered this : ', W_Input.data, end=2*' ') else : print(' Nothing was entered ') |
一个诅咒的例子,用于定时数学测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #!/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(' ') stdscr.addstr('Elapsed Time: %i '%(time.time() - s)) stdscr.addstr('This is the answer: %s '%answer) #stdscr.refresh() ##implied with the call to getch stdscr.addstr('Press any key to exit...') curses.wrapper(main) |
在Linux下,可以使用curses和getch函数,它是非阻塞的。参见GETCHE()
https://docs.python.org/2/library/curses.html网站
等待键盘输入x秒的函数(必须先初始化Curses窗口(win1)!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import time def tastaturabfrage(): inittime = int(time.time()) # time now waitingtime = 2.00 # time to wait in seconds while inittime+waitingtime>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 |