我正在编写一个带有无限 while 循环的程序,该循环运行一个函数,该函数从用户那里获取输入,然后打印到控制台。我希望能够做一些事情,比如有一段单独的代码不断检查作为后台进程的时间,并在某个时间向控制台打印一条消息并询问您是否要退出编程或继续 while 循环。我认为我需要多线程或类似的东西。
def main():
while True:
x = input("Write Something: ")
print(x)
main()
我正在编写一个带有无限 while 循环的程序,该循环运行一个函数,该函数从用户那里获取输入,然后打印到控制台。我希望能够做一些事情,比如有一段单独的代码不断检查作为后台进程的时间,并在某个时间向控制台打印一条消息并询问您是否要退出编程或继续 while 循环。我认为我需要多线程或类似的东西。
def main():
while True:
x = input("Write Something: ")
print(x)
main()
线程对此有好处,后台线程大部分时间都在休眠。您可以从这里开始。最终你会遇到很多问题 - 与领土一起出现;-)
import threading
timetoquit = False
iolock = threading.Lock()
class Watcher(threading.Thread):
def __init__(self, timeout):
threading.Thread.__init__(self)
self.timeout = timeout
self.waiter = threading.Event()
def run(self):
global timetoquit
while not timetoquit:
self.waiter.wait(self.timeout)
if timetoquit:
return
with iolock:
i = raw_input("want to quit? ")
if i.startswith("y") or i.startswith("Y"):
timetoquit = True
self.waiter.clear()
# Unused in this example, but you may want it someday ;-)
def cancel(self):
global timetoquit
timetoquit = True
self.waiter.set()
# this Watcher will ask every 10 seconds
watch = Watcher(10)
watch.start()
while not timetoquit:
# do stuff
# put console interaction in `with iolock` to
# prevent the main program and the thread from
# messing with the console at the same time
with iolock:
if not timetoquit:
whatever = raw_input("enter something ")
# do stuff
这是使用 Tim Peters 的建议的尝试threading.Timer
:
import threading
check_done = False
def are_we_done_yet():
global check_done
print("quit now?")
check_done = True
t = threading.Timer(2.0, are_we_done_yet)
t.daemon = True
t.start()
t = threading.Timer(2.0, are_we_done_yet)
t.daemon = True
t.start()
while True:
response = raw_input('>>> ')
if check_done:
if response.lower().startswith('y'): break
check_done = False
上面代码的一个问题是,没有办法区分用户想要用于>>>
提示的输入和用户对问题的响应quit now?
。
如果用户碰巧在问题弹出y
时键入了一个以 a 开头的句子,那么用户可能会无意中导致程序退出。quit now?
因此,更清洁的解决方案可能是使用 GUI:
import Tkinter as tk
import tkMessageBox
def are_we_done_yet():
if tkMessageBox.askyesno(title="Quit", message="Quit now?",
default=tkMessageBox.NO):
root.quit()
root.after(2000, are_we_done_yet)
root = tk.Tk()
root.geometry('300x200')
entry = tk.Text(root)
entry.pack()
entry.focus()
root.after(2000, are_we_done_yet)
root.mainloop()