Come eseguire un'ultima funzione, prima di essere ucciso in Python?
Domanda
C'è un modo per eseguire un ultimo comando prima dell'esecuzione di script Python viene fermato da essere ucciso da qualche altro script, interrupt della tastiera etc.
Soluzione
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 avete bisogno di recuperare altre interruzioni a livello di sistema operativo, guardare il modulo di segnalazione:
http://docs.python.org/library/signal.html
segnale Esempio
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)
Altri suggerimenti
Si potrebbe utilizzare il atexit
modulo.Con esso, è possibile registrare una funzione che verrà chiamata al termine del programma.Un esempio da qui: 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)
Si può anche passare posizionale delle parole chiave e parametri per la funzione che si desidera chiamare al termine del programma.
Si noti che ci sono un paio di circostanze elencate nei documenti in cui il gestore non sarà chiamata:
Nota:Le funzioni registrati tramite questo modulo non vengono chiamati quando il programma viene ucciso da un segnale non gestito dal Python, quando un Pitone fatale interno viene rilevato un errore, o quando
os._exit()
viene chiamato.
Come tale, è possibile che si desidera registrare anche un gestore di segnale.
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
Con le scuse per 'Unknown' per prendere la loro risposta e correggere come se fosse la mia risposta, ma le mie modifiche sono state respinte.
La risposta approvato contiene un errore che causerà un segfault.
Non è possibile utilizzare sys.exit () in un gestore di segnale, ma è possibile utilizzare os._exit in modo che diventi:
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 può essere utilizzata se la piattaforma di destinazione è Windows.
A seconda del caso d'uso e la necessità di pulizia in caso di errori fatali -. È possibile aggiungere SIGSEGV e SIGILL, ma in genere questo non è consigliato in quanto lo stato del programma può essere tale che si crea un ciclo infinito
Utilizzare il modulo atexit per registrare una funzione che verrà chiamato alla fine.
import atexit
atexit.register(some_function)