[Python] Перехватить ctrl-c в консоли
try:
.......
except KeyboardInterrupt:
print 'Fuck!'
А как при этом вернуть управление исполнявшемуся коду?
On Error Resume Next
Но вообще эта строчка мне почему-то вижуалбейсик напоминает...
Я вот почему спрашиваю: обычно отработчик(и) сигналов нажатия ^C/^Break выполняе(ю)тся асинхронно. И есть возможность запрограммировать какую-нибудь хитрую недефолтную реакцию (например, прерывание выполнения после завершения текущей стадии расчётов при однократном нажатии ^C).
такая обработка ошибок есть только в VB (из тех, что я знаю). После получения Exception вернуться штатными средствами в точку, где он возник, невозможно ни в одном языке.
как-то точно можно перехватывать ctrl-c без исключения...
ага, это, по идее, более логичный вариант...
А как при этом вернуть управление исполнявшемуся коду?ему надо делать в цикле пока не нажато, так что предложенный вариант вполне подходит.
ему надо делать в цикле пока не нажато, так что предложенный вариант вполне подходит.Вовсе не обязательно. Может ему захочется цикл нормально завершить, а не прерывать в случайном месте?
Вовсе не обязательно. Может ему захочется цикл нормально завершить, а не прерывать в случайном месте?бля, не знаешь питона, лучше бы не влезал. Есть finally.
лучше бы не влезал. Есть finally.это не то
После получения Exception вернуться штатными средствами в точку, где он возник, невозможно ни в одном языке.эээ
это континуэйшен?
он же есть во всяких там лиспах
и в сишарпе вродь писали чего-то подобное есть
Ну или я уже больше пяти лет плохо читаю документацию.
Ну или я уже больше пяти лет плохо читаю документацию.yield?
yield?да-да, там ещё много есть слов.
но причём тут это?!
это континуэйшен?ээ... нет?
Возврат в точку исключения можно сделать, но это нетривиально и, вероятно, не портируемо.
Возврат в точку исключения можно сделать, но это нетривиально и, вероятно, не портируемо.в первую очередь, это чревато труднообнаруживаемыми ошибками, из-за того, что когда вызывается обработчик ошибки контекст может быть полностью произвольным.
соответственно, в обработчике ошибки, получается вообще не понятно, на что можно расчитывать, а на что нельзя, и соответственно почти польностью нельзя использовать внешнее окружение.
Прерывание не генерит, signal.SIGBREAK существует только под винду....
Хм. А если то же самое, но для ctrl-break?А что делает Ctrl+Break?
А что делает Ctrl+Break?Это альтернатива ^C, но ещё со времён DOS'а она распознавалась как отдельный сигнал (в смысле, её, вроде, можно было отдельно отключить, а обработка их как сигналов уже в винде появилась).
А что делает Ctrl+Break?Да вот хочется как раз, чтобы делало то, что попросят
Тред появился именно потому, что после нескольких часов гугления ничего, чтобы обрабатывало сочетания клавиш в консоли я не нашел... Только для gui
Заведи отдельный тред с задачкой. Сигналы с консоли (exceptions) придут в главный тред. Там их и обработай.
А уже упомянутое ctrl-break или, например, неупомянутое alt-shift-K какое исключение выбросят?
Сигналы с консоли (exceptions) придут в главный тред. Там их и обработай.Хз как в *nix, в винде они приходят отдельным потоком, соответственно, их обработчик будет работать не прерывая работу основного потока.
А уже упомянутое ctrl-break или, например, неупомянутое alt-shift-K какое исключение выбросят?Проверь, какие вообще проблемы?
C:\temp>type 1.pyПервый запуск прерван по ^C, второй по ^Break, третий пытался прервать по Alt+Shift+K, которого в винде нет
import sys
from time import sleep
try:
sleep(10)
except BaseException:
print sys.exc_info[0]
C:\temp>python 1.py
<type 'exceptions.KeyboardInterrupt'>
C:\temp>python 1.py
^C
C:\temp>python 1.py
C:\temp>python --version
Python 2.5
Как видно, у питона 2.5 под винду весьма странный взгляд на ^Break (зачем-то отображает его как ^C).
Проверь, какие вообще проблемы?
Да в общем-то никаких. Как проблем так и исключений
#include<stdio.h>Если я правильно понимаю, аналогом для него на питоне будет следующий код:
#include<signal.h>
void handler(int num)
{
printf(" %d\n", num);
signal(num, handler);
}
main
{
int i;
signal(SIGINT, handler);
signal(SIGBREAK, handler);
for(i=0; i<100000; ++i)
printf("\r%d", i);
}
from sys import *На счёт закоменченой строки: почему-то работает и без неё.
from signal import *
def handler(num, stack):
stdout.write(" %d\n"%num)
# signal(num, handler)
signal(SIGINT, handler)
signal(SIGBREAK, handler)
for i in range(1,100000):
stdout.write("\r%d"%i)
signal.SIGBREAK существует только под винду
Если под *nix работает ^Break (как под виндой то для него, наверное, должен быть назначен какой-нибудь сигнал? Через putty ^Break ничего не прерывает.
Если под *nix работает ^Break (как под виндой)А оно и не работает
А оно и не работаетну тогда какие проблемы остались?
ну тогда какие проблемы остались?Эммм... Проблема обработки нажатия клавиш в консоли.
Эммм... Проблема обработки нажатия клавиш в консоли.Т.е., ты хочешь любые клавиши ловить/обрабатывать асинхронно, не прерывая исполнение основного потока?
Т.е., ты хочешь любые клавиши ловить/обрабатывать асинхронно, не прерывая исполнение основного потока?В идеале.
Читать из "буфера нажатий клавиш" (или как там это в сях называлось) тоже сойдет. Нашелся бы такой буфер...
И это в консоли и не windows-зависимое решение...
Так что sys.stdin, к сожалению, не вариант...
вообще никак для Ctrl-Breakа он тебе зачем? У меня сложилось впечатление, что putty его вообще не передаёт...
Ну как бы j - десятый символ. http://en.wikipedia.org/wiki/C0_and_C1_control_codes
А насчёт питона и ctrl-c, он как-то хитроумно всё делал, типа у него был свой хандлер, который тупо выставлял флажок, который периодически проверялся и для которого была даже специальная сишная функция в апи (в смысле, когда долгие вычисления делаешь, неплохо её вызывать). Почитай мануал, что ли!
насчёт питона и ctrl-cДа мы уже давно не про этот частный случай...
Почитай мануал, что лиЯ раньше был молодой и наивный и ходил и читал мануалы, когда посылали. Но того что мне нужно там не оказывалось, а было только что-то отдаленно похожее, о чем поставленная мной проблема напомнила "пославшему в мануал", но работающее совершенно иначе и к тому что нужно мне неприменимое.
Какой раздел какого мануала читать? Там где я читал до этого, про обработку клавиш в консоли не упоминалось.
ну и читай из консоли клавиши в отдельном потоке
ну и читай из консоли клавиши в отдельном потоке
Проблема не в отдельном потоке, проблема в чтении клавиш.
слушай, а используй pygame, в самом деле. Или посмотри, как они там это делают.
pygame
В консоли?
import keyboard
keyboard.add_hotkey('ctrl+c', print, args=('triggered', 'ctrl+c'))
keyboard.wait()
Оставить комментарий
feliks28
Хочется реализовать "делать в цикле, пока не нажато ctrl-c". Как это сотворить в консоли наименее безболезненно?Не под винду.