代码之家  ›  专栏  ›  技术社区  ›  Dan Oberlam

这里重写__del__()是最好的选择吗?

  •  8
  • Dan Oberlam  · 技术社区  · 11 年前

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

    在我的项目中,我正在模拟化学化合物——我有 Element 绑定到其他实例 要素 通过 Bond 例子在化学中,键经常断裂,我想有一个干净的方法来做到这一点。我当前的方法如下

    # 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
    

    这些方法中有哪一种比其他方法更可取,或者有其他我忽略的方法吗?

    2 回复  |  直到 11 年前
        1
  •  6
  •   Bakuriu    11 年前

    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%的时间,所以它肯定 不是 处理你的情况的正确方法。

        2
  •  1
  •   user395760 user395760    11 年前

    第一种方法非常乏味且容易出错。第二个很好,但 del self 在里面 Bond.breakBond 这是完全没有意义的(下面将详细介绍)。第三种是粗鲁、不可靠的,在这种情况下不起作用 完全 (由于Bond和Elements之间的循环引用, __del__ 除非您升级到Python3.4,否则永远不会调用,但即使如此,它仍然很粗糙且不可靠)。

    del name 仅删除本地 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