2016-11-15 96 views
3

任何人有任何想法如何讓我的析構函數調用對象銷燬?沒有調用的Python析構函數

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

場景:有一個運行進程的守護程序。守護進程獲取SIGTERM,並立即向進程發送一個SIGTERM。在沒有調用__del__的情況下,進程停止執行。

+0

是否仍有對該停止過程的引用? –

+4

你不能。終結者不保證運行。使用[with'語句](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement)而不是'__del __()'。然後爲'SIGTERM'設置一個信號處理程序,它引發'with'語句可以作出反應的異常。 – Kevin

+1

@Kevin:終結者不能保證運行,但是我們實際上有更多的問題,因爲當Python獲取SIGTERM時,上下文管理器'__exit__'s和'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 your_object,但即使不能保證調用__del__方法,如果仍有到該對象的引用在程序(請參閱該文檔爲__del__

因此,我認爲如果您依賴SIGTERM來關閉您的Python程序,那麼我認爲不要期望事情能夠絕對順利和可預測地發展。

+0

sys.exit引發SystemExit,所以它會自動運行'__exit__'清理代碼。 – Kevin