Capturar o interrupto Keyboard em Python durante o encerramento do programa
estou a escrever um utilitário de linha de comando em Python que, uma vez que é um código de produção, deve ser capaz de desligar limpo sem despejar um monte de coisas (códigos de erro, pilhas de traços, etc.) para a tela. Isto significa que tenho de apanhar interrupções no teclado.
Já tentei usar um bloco de pesca como:if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print 'Interrupted'
sys.exit(0)
e captando o próprio sinal (como em Este post):
import signal
import sys
def sigint_handler(signal, frame):
print 'Interrupted'
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
ambos os métodos parecem funcionar muito bem durante o funcionamento normal. No entanto, se a interromper vem durante o código de limpeza no final da aplicação, Python parece sempre imprimir algo para a tela. Apanhar a interrupção dá
^CInterrupted
Exception KeyboardInterrupt in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802852b90>> ignored
considerando que a manipulação do sinal dá
^CInterrupted
Exception SystemExit: 0 in <Finalize object, dead> ignored
ou
^CInterrupted
Exception SystemExit: 0 in <bound method MyClass.__del__ of <path.to.MyClass object at 0x802854a90>> ignored
não só estes erros são feios, eles não são muito úteis (especialmente para um usuário final sem código fonte)!
o código de limpeza para esta aplicação é bastante grande, então há uma chance decente de que este problema será atingido por usuários reais. Existir há alguma forma de apanhar ou bloquear esta saída, ou é apenas algo com que terei de lidar?
2 answers
Checkout Este tópico, tem algumas informações úteis sobre a saída e tracebacks.
Se você está mais interessado em apenas matar o programa, Tente algo assim (isto irá tirar as pernas de dentro do código de limpeza também):
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(0)
except SystemExit:
os._exit(0)
Podias ignorar SIGINTs após o encerramento começar por ligar para {[[0]} antes de iniciares o teu código de limpeza.