Pergunta

Existe alguma maneira de executar um último comando antes de um Python script em execução é interrompida por ser morto por algum outro roteiro, teclado interrupção etc.

Foi útil?

Solução

import time

try:
    time.sleep(10)
finally:
    print "clean up"

clean up
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

Se você precisa pegar outras interrupções de nível OS, olhar para o módulo de sinal:

http://docs.python.org/library/signal.html

Signal Exemplo

from signal import *
import sys, time

def clean(*args):
    print "clean me"
    sys.exit(0)

for sig in (SIGABRT, SIGBREAK, SIGILL, SIGINT, SIGSEGV, SIGTERM):
    signal(sig, clean)

time.sleep(10)

Outras dicas

Você pode usar o módulo atexit. Com ele, você pode registrar uma função que será chamado no término do programa. Um exemplo de aqui: http://docs.python.org/library/atexit.html

try:
    _count = int(open("/tmp/counter").read())
except IOError:
    _count = 0

def incrcounter(n):
    global _count
    _count = _count + n

def savecounter():
    open("/tmp/counter", "w").write("%d" % _count)

import atexit
atexit.register(savecounter)

Você também pode passar parâmetros posicionais e à função que deseja chamar no término do programa.

Note que existem algumas circunstâncias referidas nos documentos em que o manipulador não será chamado:

Nota : As funções registadas através deste módulo não são chamados quando o programa é morto por um sinal não tratado por Python, quando um erro interno fatal Python é detectado, ou quando os._exit() é chamado.

Como tal, você também pode querer registrar um manipulador de sinal.

import signal
import sys
import time

def cleanup(*args):
    print 'Exiting'
    sys.exit(0)

signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
while True:
    time.sleep(60)  # less busy loop

Com desculpas a 'Desconhecido' para tomar sua resposta e corrigi-lo como se fosse minha própria resposta, mas as minhas edições foram rejeitadas.

A resposta aprovado contém um erro que irá causar um segfault.

Você não pode usar sys.exit () em um manipulador de sinal, mas você pode usar os._exit modo que se torna:

from signal import *
import os, time

def clean(*args):
    print "clean me"
    os._exit(0)

for sig in (SIGABRT, SIGINT, SIGTERM):
    signal(sig, clean)

time.sleep(10)

SIGBREAK pode ser usado se a plataforma de destino é o Windows.

Dependendo do caso de uso ea necessidade de limpeza em caso de erros fatais -. Você pode adicionar SIGSEGV e SIGILL mas geralmente isso não é aconselhável uma vez que o estado do programa pode ser tal que você cria um loop infinito

Use o módulo atexit para registrar uma função que será chamada no final.

import atexit
atexit.register(some_function)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top