誰も私のデストラクタをオブジェクト破壊に呼び出す方法を知っていますか?Pythonデストラクタは呼び出されていません
def __del__(self):
os.unlink(self.pidfile)
シナリオ:プロセスを実行するデーモンがあります。デーモンはSIGTERMを取得し、すぐにSIGTERMをプロセスに送信します。プロセスは、__del__
を呼び出さずに実行を停止します。
誰も私のデストラクタをオブジェクト破壊に呼び出す方法を知っていますか?Pythonデストラクタは呼び出されていません
def __del__(self):
os.unlink(self.pidfile)
シナリオ:プロセスを実行するデーモンがあります。デーモンはSIGTERMを取得し、すぐにSIGTERMをプロセスに送信します。プロセスは、__del__
を呼び出さずに実行を停止します。
コメントで参照されているように、オブジェクトに__exit__
メソッドを定義し、the with statementを使用するのが、オブジェクトの「破壊」の好ましい方法です。より明白で予測可能です。
ただし、with
ステートメントを使用しても、SIGTERMが受信された場合、オブジェクトのクリーン破壊は保証されません。シグナルが受信されたときに何かを行うには、シグナルハンドラを追加する必要があります。この時点で
import signal
import sys
def handle_signal(signum, frame):
print('Got signal')
# Do some cleanup
sys.exit(signum) # Maybe ???
signal.signal(signal.SIGTERM, handle_signal)
、あなたは(__del__のためのドキュメントを参照してください)シグナルハンドラ内del your_object
を呼び出して検討するかもしれないが、そのオブジェクトへの参照がプログラム内に残っていた場合でも、そのは__del__
メソッドを呼び出すことが保証されていません
結論私は、あなたがPythonプログラムを閉じるためにSIGTERMに依存しているならば、事態が絶対にスムーズかつ予想通りに進むとは思っていません。
sys.exitは自動的に '__exit__'クリーンアップコードを実行するようにSystemExitを呼び出します。 – Kevin
まだ停止しているプロセスへの参照はありますか? –
できません。ファイナライザは動作保証されません。 '__del __()'の代わりに[with with 'statement](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)を使用してください。次に、 'with'ステートメントが反応することができる例外を発生させる' SIGTERM'のシグナルハンドラを設定します。 – Kevin
@Kevin:ファイナライザの実行は保証されていませんが、PythonがSIGTERMを取得したときにコンテキストマネージャ '__exit__'と' finally'ブロックがデフォルトで実行されないため、実際にはそれ以上の問題があります。 – user2357112