我正在寻找执行以下操作的代码片段/示例:
如果您使用的是 Unix/Linux,那么 select 模块将为您提供帮助。
import sys
from select import select
print "Press any key to configure or wait 5 seconds..."
timeout = 5
rlist, wlist, xlist = select([sys.stdin], [], [], timeout)
if rlist:
print "Config selected..."
else:
print "Timed out..."
如果您使用的是 Windows,请查看 msvcrt 模块。 (请注意,这在 IDLE 中不起作用,但在 cmd 提示符下有效)
import sys, time, msvcrt
timeout = 5
startTime = time.time()
inp = None
print "Press any key to configure or wait 5 seconds... "
while True:
if msvcrt.kbhit():
inp = msvcrt.getch()
break
elif time.time() - startTime > timeout:
break
if inp:
print "Config selected..."
else:
print "Timed out..."
Python 没有任何标准方法来捕获此问题,它只能通过 input() 和 raw_input() 获取键盘输入。
如果你真的想要这个,你可以使用 Tkinter 或 pygame 将击键捕获为“事件”。还有一些特定于平台的解决方案,例如 pyHook。但如果它对你的程序不是绝对重要,我建议你以另一种方式工作。
如果结合使用 time.sleep、threading.Thread 和 sys.stdin.read,您可以轻松等待指定的输入时间,然后继续。
t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()
我是这样做的:
import threading
import time
import sys
class MyThread(threading.Thread):
def __init__(self, threadID, name, counter, f):
super().__init__()
self.threadID = threadID
self.name = name
self.counter = counter
self.func = f
def run(self):
self.func()
class KeyboardMonitor:
def __init__(self):
# Setting a boolean flag is atomic in Python.
# It's hard to imagine a boolean being
# anything else, with or without the GIL.
# If inter-thread communication is anything more complicated than
# a couple of flags, you should replace low level variables with
# a thread safe buffer.
self.keepGoing = True
def wait4KeyEntry(self):
while self.keepGoing:
s = input("Type q to quit: ")
if s == "q":
self.keepGoing = False
def mainThread(self, f, *args, **kwargs):
"""Pass in some main function you want to run, and this will run it
until keepGoing = False. The first argument of function f must be
this class, so that that function can check the keepGoing flag and
quit when keepGoing is false."""
keyboardThread = MyThread(1, "keyboard_thread", 0, self.wait4KeyEntry)
keyboardThread.start()
while self.keepGoing:
f(self, *args, **kwargs)
def main(keyMonitorInst, *args, **kwargs):
while keyMonitorInst.keepGoing:
print("Running again...")
time.sleep(1)
if __name__ == "__main__":
uut = KeyboardMonitor()
uut.mainThread(main)
我的方法不是让阻塞调用超时,而是启动一个线程等待用户输入输入,而另一个线程则执行其他操作。这两个进程通过少量原子操作进行通信:在本例中,设置一个布尔标志。对于比原子操作更复杂的事情,显然您应该用某种线程安全缓冲区替换原子变量。