Python在更改类中对象的成员时释放内存

时间:2016-12-23 17:14:06

标签: python python-3.x class

我一直在使用IDLE中的Python对象,并观察到如果对象的成员变量发生了变化,则内存不会被释放!这是一个例子:

import weakref
import gc

class subclass():
    def __init__(self, data):
         self.data=data
    def __repr__(self):
    return self.data.__str__()

class newclass():
    def __init__(self,data):
         self.data=subclass(data)
    def test(self):
         refs=weakref.ref(self.data)()
         self.data=None
         gc.collect()
         print ("ref", refs)

a = newclass(data=3)
a.test()
print ("val", a.data)

此代码的输出,我希望是:

ref None
val None

但事实证明,ref仍然是一个有效的引用,输出是:

ref 3
val None

我希望看到内存被释放。我想了解如何。

1 个答案:

答案 0 :(得分:3)

不幸的是,你误解了一些至关重要的事情。当您调用从weakref 返回的weakref.ref对象时,您将返回原始对象。尝试打印type(ref),看看如何返回<class '__main__.subclass'>。请参阅docs on weakref.ref

  

如果指示对象仍然存在,则可以通过调用引用对象来检索原始对象;如果指示对象不再存在,则调用引用对象将导致返回None

(强调我的)

你调用了引用对象并让你的类subclass回来了;因此,对ref的引用仍然存在,不允许它被垃圾收集。

如果你不打电话,另一方面,你会注意到行print('ref', refs)如何表明引用已经死了:

ref <weakref at 0x7f3028188a48; dead>
val None

即作为对象的唯一参考,并且由于它很弱,它被收集了。

顺便说一句,如果你想在Python 2和3之间移植,你会希望你的类从object继承而不是使用空括号()。如果您不关心可移植性,则可以删除括号而不改变语义。 : - )