2014-02-13 48 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