If you're on Unix/Linux then the select module will help you.
如果您使用的是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..."
If you're on Windows, then look into the msvcrt module. (Note this doesn't work in IDLE, but will in cmd prompt)
如果您使用的是Windows,那么可以查看msvcrt模块。(请注意,这在空闲时不起作用,但在命令提示下会起作用)
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 doesn't have any standard way to catch this, it gets keyboard input only through input() and raw_input().
Python没有任何标准的方法来捕捉这一点,它只能通过INPUT()和RAW_INPUT()获得键盘输入。
If you really want this you could use Tkinter or pygame to catch the keystrokes as "events". There are also some platform-specific solutions like pyHook. But if it's not absolutely vital to your program, I suggest you make it work another way.
如果你真的想要这样做,你可以使用Tkinter或PYGAME来捕捉击键作为“事件”。还有一些特定于平台的解决方案,如pyHook。但如果它对你的程序不是绝对重要的,我建议你让它以另一种方式工作。
If you combine time.sleep, threading.Thread, and sys.stdin.read you can easily wait for a specified amount of time for input and then continue.
如果您组合了time、睡眠、线程、线程和sys.stdin.read,那么您可以很容易地等待指定的时间进行输入,然后继续。
t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()
Here's how I did it:
我是这样做的:
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)
Rather than make a blocking call time out, my approach is to start a thread that waits for the user to enter input, while another thread does something else. The two processes communicate through a small number of atomic operations: in this case, setting a boolean flag. For anything more complicated than atomic operations, obviously you should replace the atomic variable with a threadsafe buffer of some kind.
我的方法不是让阻塞调用超时,而是启动一个线程,等待用户输入,而另一个线程执行其他操作。这两个进程通过少量的原子操作进行通信:在本例中,设置一个布尔标志。对于任何比原子操作更复杂的操作,显然应该用某种类型的ThreadSafe缓冲区替换原子变量。
Based on idea from https://note.nkmk.me/en/python-while-usage/, and from elsewhere.
基于来自https://note.nkmk.me/en/python-while-usage/,和其他地方的想法。
Program will stop if CTRL-C is pressed withing 5 seconds, otherwise will continue.
如果按CTRL-C超过5秒,程序将停止,否则将继续。
Works on Python 3, does not need any external (pip install ...) libraries.
在Python3上运行,不需要任何外部设备(PIP安装...)图书馆。
Should work on Linux and Windows.
应该在Linux和Windows上工作。
If you wish for program to check user input more often, comment print function before time.sleep(), and change time.sleep(1) to time.sleep(0.1). You would probably use top print function, too.
如果您希望程序更频繁地检查用户输入,请在time之前对打印函数进行注释。睡眠(),并将时间。睡眠(1)更改为时间。睡眠(0.1)。您可能也会使用TOP打印功能。
import time
def fn_wait_for_user_input(seconds_to_wait,message):
#print('waiting for',seconds_to_wait, 'seconds ...' )
print (message, seconds_to_wait)
start_time = time.time()
try:
while (time.time() - start_time ) < seconds_to_wait:
'''
parenthesis, from inside out:
time.time() which is current time - start time, if it is more than 10 seconds, time's up :)
int ; so we don't count 10 -1,02=8; instead we will count 10-1 = 9, meaning 9 seconds remaining, not 8
seconds to wait - everything else ; so we get reverse count from 10 to 1, not from 1 to 10
'''
print("%d" % ( seconds_to_wait - int( (time.time() - start_time ) ) ) )
time.sleep(1)
print('No keypress detected.')
return 1 #no interrupt after x seconds
except KeyboardInterrupt:
print('Keypress detected - exiting.')
return 0 #interrupted
if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" ) == 1:
print('continuing ....')
else:
print('not continuing.')
note:
注:
use this to print all in one line:
使用此命令可在一行中打印所有内容:
print("%d" % ( seconds_to_wait - int( (time.time() - start_time ) ) ), end=' ', flush=True ) #needs flush inside loop...buffered
use this to continue inside a function:
使用此命令可在函数内部继续:
if fn_wait_for_user_input(5, "program will continue if you don't press CTRL-C within seconds:" ) == 1:
#print('continuing ....')
pass
else:
#print('not continuing.')
#exit function
return
更多回答
about the windows part: I'd strongly suggest to insert a time.sleep(0.5) at the end of the while-loop, because otherwise the process will waste quite some processor time while waiting...
关于Windows部分:我强烈建议在While循环的末尾插入一个Time。睡眠(0.5),否则进程将在等待时浪费相当多的处理器时间……
我是一名优秀的程序员,十分优秀!