Python:了解对象__del__方法

时间:2012-05-17 11:39:36

标签: python

任何人都可以形容我为什么这段代码会打印'2 1 0完成'而不是预期输出'0 1 2完成'? 据我所知,我们在列表推导过程中创建了一些匿名变量,并且使用filo原理对列表理解无法结束进行垃圾收集。 但是,它们仍然在列表aa中引用,不是吗? 为什么第二个'del a'在这种情况下没有调用 del 魔法?

class A:
    def __init__(self, name):
        self.name = name
    def __del__(self):
        print self.name,

aa = [A(str(i)) for i in range(3)]
for a in aa:
    del a

print 'done'

另外,高级问题。请查看http://codepad.org/niaUzGEy 为什么有5份,3份?这不是一份副本吗?为什么5或3?不知道,那就是为什么要问它;) 谢谢你的时间!

2 个答案:

答案 0 :(得分:7)

您混淆了del语句和__del__方法。

del a只是将名称a与其引用的任何对象取消绑定。 aa引用的列表未更改,因此对象都继续存在。

仅在对象的最后一次引用被销毁后调用__del__方法。这可能是在致电__del__之后,但通常不是。

您很少需要使用del。重新绑定aa然后释放它包含的所有对象会更加常见,如果没有其他引用,将自动调用它们的__del__方法。

此外,您很少需要使用__del__。对于大多数用途,Python对象的管理将自动处理清理。向类添加__del__方法通常是一个坏主意,因为它可能会干扰垃圾收集器,所以相反自相矛盾__del__使得程序更有可能泄漏内存。 Python也不能保证在程序退出时是否实际调用__del__,如果确实如此,你可能会发现你不能再使用的全局变量,也不能保证只调用它一次(尽管你必须这样做)跳过篮球让它不止一次打电话。)

简而言之,如果可能,请避免使用__del__

答案 1 :(得分:3)

打印done 2 1 0(CPython)。

您不会删除for循环中的列表元素。它们在退出时被删除。据我所知,__del__的调用顺序是特定于实现的,所以它在另一个实现中可能有所不同(IronPython,Jython等)。