Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python在更改类中对象的成员时释放内存_Python_Python 3.x_Class - Fatal编程技术网

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

Python在更改类中对象的成员时释放内存,python,python-3.x,class,Python,Python 3.x,Class,我一直在空闲状态下处理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,d

我一直在空闲状态下处理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

我希望看到内存被释放。我想知道是怎么回事。

不幸的是,你误解了一些重要的事情。调用从
weakref.ref
返回的
weakref
对象时,将返回原始对象。尝试打印
类型(ref)
并查看如何返回
。见:

如果引用对象仍然处于活动状态,则可以通过调用引用对象来检索原始对象;如果引用对象不再处于活动状态,调用引用对象将导致返回
None

(强调矿山)

您调用了引用对象,并获得了类
子类
;因此,
ref
中仍然存在对它的引用,不允许它被垃圾回收

另一方面,如果不调用它,您会注意到
print('ref',refs)
行如何指示引用已失效:

ref <weakref at 0x7f3028188a48; dead>
val None
ref
瓦尔诺内
i、 e作为对对象的唯一引用,由于它很弱,所以被收集


另一方面,如果您想在Python 2和Python 3之间实现可移植性,您将希望您的类从
对象
中进行子类化,而不是使用空括号
()
。如果您不关心可移植性,可以删除括号而不改变语义。:-)

不幸的是,你误解了一些重要的事情。调用从
weakref.ref
返回的
weakref
对象时,将返回原始对象。尝试打印
类型(ref)
并查看如何返回
。见:

如果引用对象仍然处于活动状态,则可以通过调用引用对象来检索原始对象;如果引用对象不再处于活动状态,调用引用对象将导致返回
None

(强调矿山)

您调用了引用对象,并获得了类
子类
;因此,
ref
中仍然存在对它的引用,不允许它被垃圾回收

另一方面,如果不调用它,您会注意到
print('ref',refs)
行如何指示引用已失效:

ref <weakref at 0x7f3028188a48; dead>
val None
ref
瓦尔诺内
i、 e作为对对象的唯一引用,由于它很弱,所以被收集


另一方面,如果您想在Python 2和Python 3之间实现可移植性,您将希望您的类从
对象
中进行子类化,而不是使用空括号
()
。如果您不关心可移植性,可以删除括号而不改变语义。:-)

在Python3中,从对象子类化是隐式的,但我认为这是一个很好的风格点,它有助于使您的代码易于移植到Python2。我们都知道,显式比隐式好:)@juanpa.arrivillaga我同意(尽管这实际上是由2ps编辑的:-)谢谢。明白了!在Python3中,从对象子类化是隐式的,但我认为这是一个很好的风格点,它有助于使您的代码易于移植到Python2。我们都知道,显式比隐式好:)@juanpa.arrivillaga我同意(尽管这实际上是由2ps编辑的:-)谢谢。明白了!