Python: дождитесь нажатия клавиши или до истечения времени ожидания

#python

#python

Вопрос:

У меня есть давно работающий скрипт Python внутри терминального сеанса (хост-машина — это блок FreeBSD), который выполняет задачу каждые 9 минут. Теперь я хотел бы иметь возможность прервать этот спящий вызов в любой момент, чтобы он сразу же выполнил задачу.

Как я могу это сделать? Перехват Ctrl C не является опцией, поскольку мне это нужно для остановки программы (а не просто прерывания режима ожидания). Все остальное, что я могу сделать с окном терминала и клавиатурой, в порядке.

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

1. «Ловить Ctrl C не вариант, так как мне это нужно для остановки программы». Что?

2. @IgnacioVazquez-Abrams, иногда мне нужно остановить программу, и самый простой способ сделать это — нажать Ctrl C. Поэтому я не хочу прерывать sleep , перехватывая KeyboardInterrupt .

3. Вам нужно иметь возможность завершить работу программы, нажав Ctrl C только один раз? Вы можете поймать его в первый раз и убить во второй. Как насчет перехвата другого сигнала?

4. Разве вы не можете просто использовать Ctrl- для этого?

5. @Thomas, я полагаю, я мог бы поймать другой сигнал. Я не уверен, как это сделать с помощью Python, но если вы уверены, что отправляете ответ, который подразумевает SIGALRM и прерывает a raw_input или что-то в этом роде, это может быть так. Однако у двойного Ctrl C будет своя доля проблем, которых я бы предпочел избежать.

Ответ №1:

По предложению Томаса я придумал эту функцию:

 import signal

def input_or_timeout(timeout):
    def nothing(sig, frame): pass
    signal.signal(signal.SIGALRM, nothing)
    signal.alarm(timeout)
    try:
        raw_input()
        signal.alarm(0)
    except (IOError, EOFError): pass
  

Он ожидает ввода не более timeout нескольких секунд.

В Windows, я полагаю, вы могли бы заменить raw_input() на getch() from msvcrt .

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

1. В Windows вы вообще не можете использовать этот код, потому что он не поддерживает SIGALRM.