如何设置 raw_input 的时间限制
- 2024-12-24 08:55:00
- admin 原创
- 122
问题描述:
在 python 中,有没有一种方法可以在等待用户输入时计算时间,以便在 30 秒后raw_input()
自动跳过该功能?
解决方案 1:
不幸的是,@jer 推荐的解决方案所基于的signal.alarm函数仅适用于 Unix。如果您需要跨平台或特定于 Windows 的解决方案,则可以基于threading.Timer,使用thread.interrupt_mainKeyboardInterrupt
从计时器线程向主线程发送一个。即:
import thread
import threading
def raw_input_with_timeout(prompt, timeout=30.0):
print(prompt, end=' ')
timer = threading.Timer(timeout, thread.interrupt_main)
astring = None
try:
timer.start()
astring = input(prompt)
except KeyboardInterrupt:
pass
timer.cancel()
return astring
无论是 30 秒超时还是用户明确决定按下 Control-C 放弃输入任何内容,这都将返回 None ,但以相同的方式处理这两种情况似乎可以(如果您需要区分,您可以使用自己的计时器函数,在中断主线程之前,在某处记录发生超时的事实,并在访问处理程序中的KeyboardInterrupt
“某处”以区分发生了两种情况中的哪一种)。
编辑:我本可以发誓这是可行的,但我一定是错了——上面的代码省略了显然需要的timer.start()
,即使有了它,我也无法让它再工作。 select.select
显然是要尝试的另一件事,但它不适用于 Windows 中的“普通文件”(包括 stdin)——在 Unix 中它适用于所有文件,在 Windows 中,仅适用于套接字。
所以我不知道如何实现跨平台的“带超时的原始输入”。可以使用紧密循环轮询msvcrt.kbhit来构建特定于 Windows 的程序,执行msvcrt.getche
(并检查它是否返回以指示输出已完成,在这种情况下它会跳出循环,否则会累积并继续等待)并检查超时时间(如果需要)。我无法测试,因为我没有 Windows 机器(它们都是 Mac 和 Linux),但这里是我建议的未经测试的代码:
import msvcrt
import time
def raw_input_with_timeout(prompt, timeout=30.0):
print(prompt, end=' ')
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
原作者在评论中表示他不想return None
在超时时这样做,但还有什么其他选择呢?抛出异常?返回不同的默认值?无论他想要什么替代方案,他都可以清楚地将其替换为我的return None
;-)。
如果您不想因为用户打字缓慢(而不是根本没有打字!-)而超时,您可以在每次成功输入字符后重新计算 finishat。
解决方案 2:
我在一篇博客文章中找到了解决这个问题的方法。以下是该博客文章中的代码:
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 操作系统*。
解决方案 3:
input() 函数旨在等待用户输入一些内容(至少是 [Enter] 键)。
如果您不打算使用 input(),下面是使用 tkinter 的更轻松的解决方案。在 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('
You entered this : ', W_Input.data, end=2*'
')
else : print('
Nothing was entered
')
解决方案 4:
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 文档,你就会清楚这段代码中刚刚发生了什么!!
解决方案 5:
一个用于定时数学测试的 curses 示例
#!/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)
解决方案 6:
在 Linux 下,可以使用 curses 和 getch 函数,它是非阻塞的。请参阅 getch()
https://docs.python.org/2/library/curses.html
等待键盘输入 x 秒的函数(您必须先初始化一个 curses 窗口(win1)!
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
解决方案 7:
这是针对较新的 Python 版本,但我相信它仍能回答这个问题。它的作用是向用户发送一条消息,告知用户时间已到,然后结束代码。我相信有办法让它跳过输入而不是完全结束代码,但无论哪种方式,这至少应该有所帮助……
import sys
import time
from threading import Thread
import pyautogui as pag
#imports the needed modules
xyz = 1 #for a reference call
choice1 = None #sets the starting status
def check():
time.sleep(15)#the time limit set on the message
global xyz
if choice1 != None: # if choice1 has input in it, than the time will not expire
return
if xyz == 1: # if no input has been made within the time limit, then this message
# will display
pag.confirm(text = 'Time is up!', title = 'Time is up!!!!!!!!!')
sys.exit()
Thread(target = check).start()#starts the timer
choice1 = input("Please Enter your choice: ")
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)