6

我正在尝试找出删除某些东西的最佳方法,最好不必编写大量代码。

在我的项目中,我正在模拟化合物 - 我通过实例将实例Element绑定到其他实例。在化学中,键经常断裂,我希望有一个干净的方法来做到这一点。我目前的方法如下ElementBond

# 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

这些方法中的任何一种都比其他方法更可取,还是有其他我忽略的方法?

4

2 回答 2

6

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 中,释放将立即完成(在这个简单的情况下),但是在该语言的其他实现中,解释器可能不会立即释放列表。

另请注意,__del__的文档引用了这一事实。此外,它是一种非常低级的方法,您在 99.9% 的时间都不需要,因此它肯定不是处理您的情况的正确方法。

于 2014-02-13T22:14:34.967 回答
1

The first way is pretty tedious and error-prone. The second is fine, but the del self in Bond.breakBond is completely and utterly pointless (more on this below). The third is hacky, unreliable, and in this specific case not working at all (due to the circular reference between Bond and Elements, __del__ is never invoked unless you upgrade to Python 3.4, but even then it remains hacky and unreliable).

del name only removes the local name, it does not call __del__ or otherwise affect the object. It has absolutely no effect on memory management, except possibly allowing earlier garbage collection if name was the last (reachable) reference.

You should do this:

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 
于 2014-02-13T22:15:25.710 回答