1

谁能描述我为什么这段代码会打印'2 1 0 done'而不是预期的输出'0 1 2 done'?据我所知,我们在列表推导期间创建了一些匿名变量,并且在列表推导覆盖结束时使用 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份?这不应该是1份吗?为什么是 5 或 3?不知道,这就是为什么要问它;)感谢您的时间!

4

2 回答 2

7

You are confusing the del statement and the __del__ method.

del a simply unbinds the name a from whatever object it referenced. The list referenced by aa is unchanged so the objects all continue to exist.

The __del__ method is only called after the last reference to an object has been destroyed. That could be after a call to __del__ but usually isn't.

You rarely need to use del. It would be much more common just to rebind aa and then all the objects it contains will be released, and if not otherwise referenced their __del__ methods will be called automatically.

Also, you rarely need to use __del__. For most purposes Python's management of objects will handle cleanup automatically. Adding a __del__ method to a class is generally a bad idea as it can interfere with the garbage collector, so rather paradoxically __del__ makes it more likely that your program will leak memory. Also Python won't guarantee whether __del__ is actually called on program exit, and if it does you may find global variables you cant to use no longer exist, nor will it guarantee to only call it once (though you have to jump through hoops to make it call it more than once).

In short, avoid using __del__ if you possibly can.

于 2012-05-17T12:01:46.103 回答
3

它打印done 2 1 0(CPython)。

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

于 2012-05-17T11:45:58.213 回答