0

I have been playing around with Python objects in IDLE and observed that if a member variable of an object is changed, the memory isn't released! Here is an example:

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)

The output of this code, I would expect to be:

ref None
val None

It turns out that the ref, however, is still a valid reference and the output is:

ref 3
val None

I would like to see that memory being released. I would like to understand how.

1 Answer 1

3

You've misunderstood something crucial, unfortunately. When you call the weakref object returned from weakref.ref you get back the original object. Try printing type(ref) and see how <class '__main__.subclass'> is returned. See the docs on weakref.ref:

The original object can be retrieved by calling the reference object if the referent is still alive; if the referent is no longer alive, calling the reference object will cause None to be returned.

(Emphasis mine)

You called the reference object and got your class subclass back; a reference to it therefore still exists in ref not allowing it to get garbage-collected.

If you don't call it, on the other hand, you'll notice how the line print('ref', refs) indicates that the reference is dead:

ref <weakref at 0x7f3028188a48; dead>
val None

i.e as the sole reference to your object and due to the fact it is weak, it got collected.

As an aside, if you want to be portable between Python 2 and 3 you'll want your classes to subclass from object and not use empty parentheses (). If you don't care about portability, the parentheses can be dropped without change in semantics. :-)

Sign up to request clarification or add additional context in comments.

3 Comments

In python 3 subclassing from object is implicit, but I think it is a good stylistic point and it helps make your code easily portable to Python 2. And, as we all know, explicit is better than implicit :)
@juanpa.arrivillaga I agree (even though that was actually edited in by 2ps :-)
Thanks. Got it now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.