繁体   English   中英

如何在用户输入时中断 Python 程序?

[英]How to interrupt Python program on user input?

我正在编写一个以某种标准方式执行的程序,除非用户在终端中输入某些内容,在这种情况下,程序应该改变行为,例如

while True:
    # do something here

def interrupt(user_input):
    if user_input == "some command":
        sys.exit(0) # e.g.

如何通过在while循环中没有input()来实现这一点?

这里最简单的解释是使用守护线程。

为了在 Python 中实现这一点,您可以使用多线程。 为此,有threading模块。

通过在创建线程时设置daemon=True ,您的守护程序将在后台运行。

下面是一个简单的例子。 您的主要逻辑将是 function 中的main while True无限循环侦听用户输入并在用户输入与某个预定义值匹配时终止程序(在本例中为"kill" )。

import sys
import threading

def main():
    print('Main program')
    while True:
        pass
        # Rest of main program

main_thread = threading.Thread(name='main program',
                               target=main, daemon=True)
main_thread.start()
while True:
    if input().lower() == 'kill':
        print('Terminating program')
        # Add some possible cleanup code here
        sys.exit(0)

请注意 Python 文档中有关如何停止守护线程的重要信息:

守护程序线程在关闭时突然停止。 它们的资源(如打开的文件、数据库事务等)可能无法正常释放。 如果您希望线程优雅地停止,请将它们设为非守护进程并使用合适的信号机制,例如事件。

也就是说,这种方法可能足以满足您的目的。 根据您的程序逻辑,如果需要一些清理代码,可以在退出之前完成 - 因为一旦sys.exit(0) ,守护线程将被突然终止。

然而,更通用的解决方案是使用threading.Event

这是与上述完全不同的方法,因为我们创建了一个常规的非守护线程并将一个Event传递给它。 这一次,我们没有在用户输入时突然退出程序,而是setEvent的内部标志。

并行地,一旦设置了Eventmain function 使用非阻塞is_set()来中断循环,而不是while True无限循环。

import threading

def main(e):
    print('Main program')
    while not e.is_set():
        pass
        # Rest of main program
    print('Exiting')
    # Add some possible cleanup code here

e = threading.Event()

main_thread = threading.Thread(name='main program',
                               target=main, args=(e,))
main_thread.start()

while True:
    if input().lower() == 'kill':
        print('Terminating program')
        e.set()
        break

main_thread.join()

与所描述的守护程序方法相比,这有两个优点:

  1. 您可以轻松拥有多个Event并让您的程序以不同的方式运行,具体取决于这些事件。 您还可以使用阻塞Event.wait()代替Event.is_set()
  2. 任何清理代码都可以直接由main() function 管理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM