Я пишу утилиту командной строки на Python, которая, поскольку это производственный код, должна иметь возможность корректно завершать работу, не выводя кучу вещей (коды ошибок, трассировки стека и т. д.) на экран. Это означает, что мне нужно перехватывать прерывания клавиатуры.
Я пробовал использовать как блок try catch, например:
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print 'Interrupted'
sys.exit(0)
и поймать сам сигнал (как в этот пост а>):
import signal
import sys
def sigint_handler(signal, frame):
print 'Interrupted'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
Оба метода работают достаточно хорошо при нормальной работе. Однако, если прерывание происходит во время кода очистки в конце приложения, Python всегда что-то выводит на экран. Перехват прерывания дает
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
тогда как обработка сигнала дает либо
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
or
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
Эти ошибки не только уродливы, но и не очень полезны (особенно для конечного пользователя без исходного кода)!
Код очистки для этого приложения довольно большой, поэтому есть неплохая вероятность того, что с этой проблемой столкнутся реальные пользователи. Есть ли способ поймать или заблокировать этот вывод, или это просто то, с чем мне придется иметь дело?
sys.stdout
/sys.stderr
? Нравитсяsys.stderr = open(os.devnull, 'w')
?. Если вас действительно не волнует конечный результат, то это кажется очевидным решением. - person Bakuriu   schedule 14.01.2014os._exit
, но мне кажется, что это носовые демоны. Где ваш код очистки? Используете ли вы модуль atexit для тот? - person wim   schedule 14.01.2014/dev/null
. Вы можете написать собственный файлоподобный объект, который скрывает только сообщения с заданным форматом. - person Bakuriu   schedule 14.01.2014