Проклятия Python: быстрый выход из программы

#python #ncurses #python-curses

#python #ncurses #python-проклятия

Вопрос:

Каков наилучший способ быстрого выхода из программы на Python с бесконечным циклом, использующим модуль curses?

Я попытался добавить метод 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’ для выхода из программы. Но все равно может потребоваться до 8 секунд для выхода после нажатия ‘q’ один раз.

По очевидным причинам это не кажется лучшим способом выхода из программы. Я уверен, что должно быть лучшее (более быстрое) решение.

В остальном программа работает нормально. Это 2 файла с более чем 300 строками, поэтому я публикую только соответствующие части кода с моими попытками решения.

Ответ №1:

Учитывая, что у вас уже есть nodelay, обычный подход заключается в использовании napm с небольшим (20-50 миллисекунд) временем и достижении вашей цели в 5 секунд, для запуска функций после нескольких (10-25) повторений цикла getch / napms.

Смешивание проклятий и стандартного ввода-вывода на самом деле не работает хорошо, если вы не позаботитесь о том, чтобы сбросить данные при переключении между ними.

Комментарии:

1. Это именно то, что я искал! Для этого пришлось поместить цикл в отдельную функцию, поскольку выход из цикла getch / napms, очевидно, не приведет к выходу из основного цикла. Поэтому я заменил break внутри цикла getch / napms на return . Спасибо.

Ответ №2:

Вероятно, происходит то, что ваш 'q' находится между getch() sleep вызовами и . Учитывая, что getch() выполнение занимает долю секунды и sleep блокирует программу на 5 секунд, очень вероятно, что каждый раз, когда вы нажимаете клавишу, вы будете ждать.

Самый простой способ выйти из любого скрипта python — нажать Ctrl-C — это создает KeyBoardInterrupt исключение, которое можно обработать следующим образом:

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

Конечно, если это должно быть пользовательское приложение, этого может быть недостаточно. Но также маловероятно, что какое-либо производственное приложение будет работать без полного цикла событий и пользовательского интерфейса, который позволил бы им выйти.

Наконец, если вам нужен другой способ сделать то, что вы уже делаете, вы можете использовать:

 import sys
sys.stdin.read(1)
  

Для чтения 1 bye пользовательского ввода за раз. Ctrl-C На вашем месте я бы выбрал маршрут.

Комментарии:

1. Я предпочитаю не использовать Ctrl-C для этого приложения. Но спасибо, что показали, как обращаться KeyBoardInterrupt . Я добавил это в свой код на всякий случай.