我正在编写一个带有无限while循环的程序,该循环运行一个函数,该函数从用户获取输入然后打印到控制台。我希望能够做一些事情,就像拥有一段单独的代码,不断地将时间作为后台进程检查,并在某个时间,向控制台输出一条消息,并询问您是否要退出编程或继续while循环。 我假设我需要多线程或类似的东西。
def main():
while True:
x = input("Write Something: ")
print(x)
main()
答案 0 :(得分:2)
线程对此有好处,后台线程将花费大部分时间休眠。这是你可以开始的东西。你最终会遇到很多问题 - 来自领土; - )
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
答案 1 :(得分:1)
以下尝试使用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
问题时键入以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()