2014-02-13 79 views
4

我想弄清楚最好的方法來刪除的東西,最好不用寫很多代碼。重寫__del __()是最好的選擇嗎?

在我的項目中,我模擬化合物 - 我通過Bond實例將Element實例綁定到其他Element實例。在化學債券往往破產,我想有一個乾淨的方式來做到這一點。我現在的方法是一樣的東西如下

# aBond is some Bond instance 
# 
# all Element instances have a 'bondList' of all bonds they are part of 
# they also have a method 'removeBond(someBond)' that removes a given bond 
# from that bondList 
element1.removeBond(aBond) 
element2.removeBond(aBond) 
del aBond 

我要像做

aBond.breakBond() 

class Bond(): 
    def breakBond(self): 
     self.start.removeBond(self) # refers to the first part of the Bond 
     self.end.removeBond(self) # refers to the second part of the Bond 
     del self 

或者,這樣的事情就可以了

del aBond 

class Bond(): 
    def __del__(self): 
     self.start.removeBond(self) # refers to the first part of the Bond 
     self.end.removeBond(self) # refers to the second part of the Bond 
     del self 

是這些方式中的任何一個比其他人更喜歡這樣做,還是有其他方法可以做到這一點,我忽略了?

回答

5

Python使用垃圾收集來管理內存,這意味着你做不是必須刪除任何東西。這個類是罰款:

class Bond(): 
    def breakBond(self): 
     self.start.removeBond(self) 
     self.end.removeBond(self) 

注意del從內存中刪除任何東西!它只是刪除一個參考一個對象,但對象可以有不止一個參考:

>>> some_list = [1,2,3] 
>>> b = some_list 
>>> del b # destroys the list? 
>>> b 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'b' is not defined 
>>> some_list # list is still there! 
[1, 2, 3] 
>>> c = some_list 
>>> del some_list 
>>> c  # list is still there! 
[1, 2, 3] 
>>> del c 

最後del c解釋後,可以解除分配名單。在CPython中,釋放將立即完成(在這種簡單情況下),但是在其他語言實現中,解釋器可能不會立即釋放列表。請注意0​​的文檔引用了這個事實。此外,它是一個真的低級別的方法,你不需要99.9%的時間,所以它當然是不是正確的方式來處理你的情況。

+0

謝謝,這基本上就是我期待我需要做的。謝謝(也)澄清德爾如何工作,我從來沒有真正明白 – Dannnno

1

第一種方法非常繁瑣且容易出錯。第二個是好的,但del selfBond.breakBond是完全和完全沒有意義(更多在這下面)。第三個是hacky,不可靠,並且在這個特定的情況下根本沒有工作(由於Bond和Elements之間的循環引用,除非你升級到Python 3.4,否則它將永遠不會被調用,但即使如此它仍然是hacky和不可靠的)。

del name只刪除本地name,它不會調用__del__或以其他方式影響對象。它對內存管理完全沒有影響,除非可能允許更早的垃圾回收,如果name是最後一個(可到達的)引用。

你應該這樣做:

aBond.breakBond() 

class Bond(): 
    def breakBond(self): 
     self.start.removeBond(self) # refers to the first part of the Bond 
     self.end.removeBond(self) # refers to the second part of the Bond 
+0

所以對於最後一個,如果我使用'aBond .__ del __()'會起作用嗎? – Dannnno

+0

@Dannnno它會運行你的代碼,即調用'self.end.removeBond(self)'和'self.start.removeBond(self)'。它不會釋放任何物體或類似的東西。 – delnan