2016-11-15 20 views
3

誰も私のデストラクタをオブジェクト破壊に呼び出す方法を知っていますか?Pythonデストラクタは呼び出されていません

def __del__(self): 
    os.unlink(self.pidfile) 

シナリオ:プロセスを実行するデーモンがあります。デーモンはSIGTERMを取得し、すぐにSIGTERMをプロセスに送信します。プロセスは、__del__を呼び出さずに実行を停止します。

+0

まだ停止しているプロセスへの参照はありますか? –

+4

できません。ファイナライザは動作保証されません。 '__del __()'の代わりに[with with 'statement](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)を使用してください。次に、 'with'ステートメントが反応することができる例外を発生させる' SIGTERM'のシグナルハンドラを設定します。 – Kevin

+1

@Kevin:ファイナライザの実行は保証されていませんが、PythonがSIGTERMを取得したときにコンテキストマネージャ '__exit__'と' finally'ブロックがデフォルトで実行されないため、実際にはそれ以上の問題があります。 – user2357112

答えて

2

コメントで参照されているように、オブジェクトに__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に依存しているならば、事態が絶対にスムーズかつ予想通りに進むとは思っていません。

+0

sys.exitは自動的に '__exit__'クリーンアップコードを実行するようにSystemExitを呼び出します。 – Kevin

関連する問題