Python 诅咒:快速退出程序

Python Curses: Exiting a program fast

快速退出带有使用 curses 模块的无限循环的 Python 程序的最佳方法是什么?

我试过在循环的末尾添加 nodelay() 方法和这个方法:

if screen.getch() == ord('q'):
    break

但是,在循环的一次迭代中进行所有函数调用需要 2-3 秒。并且由于应用程序,运行 循环比每 5 秒更频繁是没有意义的。这意味着为了让我退出程序的方式起作用,我有时必须按住 'q' 2-8 秒。

我的代码如下所示:

import curses
import time

def main(screen):
    refresh_rate = 5
    screen.nodelay(1)

    # Infinite loop. Displays information and updates it 
    # every (refresh_rate) # of seconds

    while True:

        # Makes several http requests 
        # and passes responses through multiple functions

        # Escape infinite loop
        if screen.getch() == ord('q'):
            break

        # Wait before going through the loop again
        time.sleep(refresh_rate)

if __name__ == "__main__":
    curses.wrapper(main)

我的另一个解决方案是将 while True 替换为:

loop = 1
while loop:

    #Loop code

if screen.getch() == ord('q'):
    loop = -1

这样就不用长按'q'退出程序了。但是按一次'q'后仍然需要8秒才能退出。

出于显而易见的原因,这似乎不是退出程序的最佳方式。我很确定应该有更好(更快)的解决方案。

除此之外,该程序运行良好。这是 2 个文件,超过 300 行,所以我只发布代码的相关部分和我尝试的解决方案。

可能发生的情况是您的 'q' 出现在 getch()sleep 调用之间。鉴于 getch() 需要几分之一秒的时间来执行并且 sleep 将程序锁定 5 秒,很可能任何时候你按下一个键你都会等待。

退出任何 python 脚本的最简单方法是按 Ctrl-C - 它会产生一个 KeyBoardInterrupt 异常,可以像这样处理:

try:
while True:
    do_something()
except KeyboardInterrupt:
    pass

诚然,如果这是一个面向用户的应用程序,那可能还不够。但是,如果没有完整的事件循环和允许它们退出的 UI,任何生产应用程序也不太可能运行。

最后,如果你想用另一种方式做你已经在做的事情,你可以使用:

import sys
sys.stdin.read(1)

一次读取用户输入的 1 个字节。如果我是你,我会选择 Ctrl-C 路线。

鉴于您已经有了 nodelay,通常的方法是使用短时间(20-50 毫秒)的 napms,并解决您的 5 秒目标,运行 几个(10 毫秒)后的函数-25) getch/napms 循环的重复。

混合使用 curses 和标准 I/O 效果不佳,除非您在两者之间切换时注意冲洗。