Comment exécuter une dernière fonction avant de se faire tuer en Python?
Question
Est-il possible d'exécuter une dernière commande avant un script Python en cours d'exécution est arrêté par être tué par un autre scénario, le clavier d'interruption etc.
La solution
import time
try:
time.sleep(10)
finally:
print "clean up"
clean up
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
Si vous avez besoin d'attraper d'autres interruptions de niveau OS, regardez le module de signal:
http://docs.python.org/library/signal.html
Exemple Signal
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)
Autres conseils
Vous pouvez utiliser le module atexit
. Avec elle, vous pouvez enregistrer une fonction qui sera appelée à la fin du programme. Un exemple d'ici: 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)
Vous pouvez également passer des paramètres de position et de mots clés à la fonction que vous voulez appeler à la fin du programme.
Notez qu'il ya quelques circonstances énumérées dans la documentation où votre gestionnaire ne sera pas appelé:
Note : Les fonctions enregistrées via ce module ne sont pas appelés lorsque le programme est tué par un signal non manipulé par python, lorsqu'une erreur interne fatale python est détectée, ou lorsque
os._exit()
est appelée.
En tant que tel, vous voudrez peut-être enregistrer également un gestionnaire de signal.
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
excuses à « Unknown » pour prendre leur réponse et la corriger comme si elle était ma propre réponse, mais mes modifications ont été rejetées.
La réponse approuvée contient une erreur qui va provoquer une erreur de segmentation.
Vous ne pouvez pas utiliser sys.exit () dans un gestionnaire de signaux, mais vous pouvez utiliser os._exit pour qu'il devienne:
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 peut être utilisé si la plate-forme cible est Windows.
En fonction du cas d'utilisation et la nécessité de nettoyage en cas d'erreurs fatales -. Vous pouvez ajouter SIGSEGV et SIGILL mais généralement ce n'est pas conseillé car l'état du programme peut être telle que vous créez une boucle infinie
Utilisez le module atexit pour enregistrer une fonction qui sera appelée à la fin.
import atexit
atexit.register(some_function)