2015-02-06 51 views
0

在這個僞代碼中,o的析構函數從不被調用。Python + PyQt +線程|析構函數從來沒有調用過,沒有其他的引用剩下

class MyObj(): 
    def __del__(): 
     print "Destroyed!" 
     do_upon_death() 

def parse(): 
    o = MyObj() 
    print "Ok so far..." 
    raise Exception 

run_in_QThread(parse) 

do_other_things() 

我看到印刷在終端上的異常,但似乎o沒有被垃圾收集。解釋器在異常時不會退出(主線程繼續運行)。

這個背後的全部目的是在異常發生時能夠在析構函數中進行某些清理。

另一種方式來解釋,這是一個不同的模式:

try: 
    run_in_thread(parse) 
except: 
    print "Will I ever get printed?" 

例外parse發生不會被抓到。

更進一步:

with MyContextManager() as manager: 
    run_in_thread(lambda: do_something(manager)) 

這裏manager.__exit__()將調用一切None參數如同代碼乾淨完成,即使在do_something例外。

這背後的目的是因爲我正在運行某些任務,這些任務可能由於太多不同的原因而失敗,這些任務可以在主線程中部分完成,部分在工作線程中完成。它可能會失敗。因此,我最初的想法是在任務運行時保持對象的引用,所以如果通過退出上下文或異常完成任務,引用將會丟失,並最終運行析構函數。

我試圖跟蹤這些任務,並在GUI上保留一個視覺指示器,這些任務仍然在執行他們的工作。

+1

閱讀['__del__']的文檔(https://docs.python.org/3/reference/datamodel.html#object.__del__)。 – ekhumoro 2015-02-06 22:21:44

+0

我閱讀文檔。有更深層次的想法 – jpcgt 2015-02-07 04:32:37

回答

0

你能趕上例外它被提出後,做你想做的事

try: 
    o = MyObj() 
    print "Ok so far..." 
    raise Exception 

except Exception: 
    del o 

或使用這種形式是什麼,如果是無差異的異常升高或不:

finaly: 
    del o 

如果您需要只是保持線程活着,可能是,你應該使用:Thread.sleep()

正如我在線程理解只有parse(),所以你需要通過發射()關於刪除和創建信號在主要發送hread

我認爲,堅持破壞器不是最好的決定,最好是抓住一些信號。請添加更多關於你爲什麼這麼做的信息。

+0

我剛加了一些細節。謝謝。 – jpcgt 2015-02-13 18:11:04

相關問題