#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
. Я добавил это в свой код на всякий случай.