2

使用 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 行的文件,所以我只发布了代码的相关部分以及我尝试的解决方案。

4

2 回答 2

2

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

混合curses和标准I/O并不能很好地工作,除非你在两者之间切换时注意刷新。

于 2016-10-06T08:58:33.957 回答
1

可能发生的情况是您'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条路线。

于 2016-10-06T02:40:14.050 回答