実行中のPythonスクリプトが他のスクリプト、キーボード割り込みなどによって強制終了される前に、最後の1つのコマンドを実行する方法はありますか?.
import time
try:
time.sleep(10)
finally:
print "clean up"
clean up
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
他のOSレベルの割り込みをキャッチする必要がある場合は、シグナルモジュールを確認してください。
http://docs.python.org/library/signal.html
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)
atexit
モジュールを使用できます。これにより、プログラム終了時に呼び出される関数を登録できます。ここからの例: 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)
_
プログラムの終了時に呼び出す関数に、位置パラメーターとキーワードパラメーターを渡すこともできます。
ドキュメントにリストされている、ハンドラーが呼び出されない状況がいくつかあることに注意してください。
注:このモジュールを介して登録された関数は、プログラムがPythonによって処理されないシグナルによって強制終了された場合、a Python致命的な内部エラーが検出された場合、または
os._exit()
が呼び出された場合。
そのため、シグナルハンドラーも登録することをお勧めします。
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
彼らの答えを自分の答えであるかのように訂正してくれたことを「不明」に謝罪しましたが、私の編集は拒否されました。
承認された回答には、セグメンテーション違反の原因となるエラーが含まれています。
シグナルハンドラーでsys.exit()を使用することはできませんが、os._exitを使用して次のようにすることができます。
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)
ターゲットプラットフォームがWindowsの場合、SIGBREAKを使用できます。
ユースケースと致命的なエラーが発生した場合のクリーンアップの必要性に応じて、SIGSEGVとSIGILLを追加できますが、プログラムの状態が無限ループを作成する可能性があるため、通常はお勧めしません。
Atexitモジュールを使用して、最後に呼び出される関数を登録します。
import atexit
atexit.register(some_function)