Я пишу утиліту командного рядка в 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
або
^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')
? Якщо ви насправді не піклуєтесь про кінцевий результат, це здається очевидним рішенням.