1

我有下一个代码(在这里我尝试捕获最后一个存在的对象):

class Mogican(object):
    last = None

    def __init__(self, name):
        # print("Created")
        self.name = name
        self.prev = None
        self.next = None
        if self.__class__.last == None:
            self.__class__.last = self
            self.prev = None
            self.next = None
        else:
            self.prev = self.__class__.last
            self.__class__.last.next = self
            self.__class__.last = self
            self.next = None

    def __del__(self):
        print("Deleted")
        if self.next == None:
            print("here")
            self.__class__.last = self.prev
            self.prev.next = None
        else:
            print("no here")
            self.prev.next = self.next

            self.next.prev = self.prev

还有我的主文件 main.py:

from Mogican import Mogican

if __name__ == '__main__':
    m1 = Mogican('adin')
    m2 = Mogican('dva')
    m3 = Mogican('tree')
    m4 = Mogican('Cheture')

    # print Mogican.last.name

    print m4
    del m4

但是当我删除 m4 时,没有调用 print 但对象被删除。并且无法从该方法中找到为什么不显示打印__del__

4

1 回答 1

8

__del__Python 仅在没有对对象的引用时才从内存中删除对象(如果有,则调用它们的钩子)。

m4被 引用m3,而后者又被 引用m2,等等。因此,直到所有四个对象都被删除,Python 才能释放这些对象中的任何一个。

__del__如果您使用的是 Python 3.3 或更早版本,您仍然不会看到被调用;当您在这里创建循环引用时,即使垃圾收集器也不会释放它们,因为您的对象有__del__钩子。请参阅gc.garbage文档

具有__del__()方法并且是引用循环一部分的对象会导致整个引用循环无法收集,包括不一定在循环中但只能从循环中访问的对象。Python 不会自动收集此类循环,因为通常 Python 无法猜测运行这些__del__()方法的安全顺序。

Python 3.4 实现了PEP 442,消除了这个限制。

如果您不希望某些引用计入对象生命周期或被视为循环引用,则应使用弱引用。

您可以使用weakref.WeakSet()类级别的对象,将您的实例添加到其中。如果调用时该集合为__del__,则您的最后一个实例已被删除。

于 2014-11-23T21:47:10.413 回答