[英]How do I let the user pause a python script at predefined points?
说我有很多工作要做,所以我想让用户选择暂停和/或停止工作。 但是我不希望最终出现一个不一致的状态,所以我只能暂停并退出程序中的某些点。
我如何实现我可以使用的user_requested_pause()
方法?
for item in some_very_large_list:
do_work()
# can't stop here
do_more_work()
# now we could pause.
if user_requested_pause():
# ask user how to proceed, then continue or exit with consistent state
我想过只使用ctrl + c但是KeyboardInterrupt
可以在任何时候出现。
理想情况下,我会检查stdin
上是否有输入,但我还没有找到办法。 read()
只是阻塞,如果没有输入会暂停程序,即使用户不想要它。
编辑:我解决了如下:
import signal
pause_requested = False
def handler(signum, frame):
global pause_requested
pause_requested = True
for item in some_very_large_list:
do_work()
do_more_work()
if pause_requested:
# ask user how to proceed, then continue or exit with consistent state
pause_requested = False
您可以通过使处理程序设置一个标志来告诉程序暂停并等待输入,从而可以使用signal
模块 。
您可以使用多线程来创建单独的线程来执行工作,并定期检查状态变量requested_pause
。 主线程然后在请求使用input()
的循环中运行,并在有条目时相应地设置requested_pause
。
如果您希望在没有用户干预的情况下继续执行(而不是默认暂停,要求用户重新启动),则需要使用辅助线程,协同程序或进程来接受用户输入并设置某种标记,这是最佳解决方案暂停的主要处理线程。 这可以通过多种方式实现,但我将演示仅使用python标准库和内置函数。 其他方法可能更灵活(例如检测特定按键或使用图形界面而不是命令行),但很快就会遇到兼容性问题,因为检测硬件输入通常是使用GUI库完成的,并且系统之间通常略有不同。 像keyboard
这样的库是相当不错的,但即使是这个也有一点需要注意(在Linux上需要root)。
示例代码使用线程等待input()
函数(用户按回车键):
import threading, time
class user_input_thread(threading.Thread):
def __init__(self, event_obj):
super().__init__()
self.daemon = True
self.event_obj = event_obj
def run(self):
while True:
self.event_obj.wait() #wait for the user to resume processing from main thread
print('process resumed')
input('press enter to pause\n') #use raw_input() for python 2.x
print('process will pause')
self.event_obj.clear() #clear the flag forcing processing to stop
def main_work(event_obj, *args):
for x in range(10):
if not event_obj.is_set():
input('press enter to resume') #use raw_input() for python 2.x
event_obj.set()
time.sleep(2) #heavy computation that can't be interrupted
print('done with task {}'.format(x))
if __name__ == '__main__':
event_obj = threading.Event() #work starts paused
user_input_thread(event_obj).start()
main_work(event_obj)
由于纯python的一些限制,这不是一个完美的解决方案,因为线程(即使它是一个守护进程)不会在程序结束时退出,因为它仍在等待用户输入。 这要求你按Enter键来终止程序(尽管所有的工作都会很好,而解释器只会在文件末尾等待)。 通过print语句和一些额外的控制逻辑的附加用户指令可以使这更好,但不会在很大程度上改变功能。 另一种选择只是try: except:
在主文件的循环中设置/清除一个标志,一个工作线程执行主要工作经常检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.