-1

There are many questions out there regarding this subject which I already checked. Example dated 2014!

One can also find the 'canonical' documentation here.

I don't know why I cannot reproduce the docs:

import weakref, gc
class A:
    pass
a = A()
b = weakref.ref(a)
a
Out[5]: <__main__.A at 0x250f782f3a0>
b()
Out[6]: <__main__.A at 0x250f782f3a0>
del a
b()
Out[8]: <__main__.A at 0x250f782f3a0>
gc.collect()
Out[9]: 9
b()
Out[10]: <__main__.A at 0x250f782f3a0>

b should be returning None but is not.

EDIT

Interestingly, this question on which I am interested as well, remains unanswered since a couple of years as well. Just tagging in case somebody can address both in one shot.

(Windows 10, python 3.8, Conda env)

user2357112
  • 260,549
  • 28
  • 431
  • 505
deponovo
  • 1,114
  • 7
  • 23
  • 2
    The REPL may have a reference to the object when you printed it. – Barmar Oct 06 '21 at 12:41
  • But if I explicitly call `del` on `a`, should it be removed entirely? And `gc.collect()` is also explicitly called. – deponovo Oct 06 '21 at 12:52
  • 2
    I'm not familiar with the environment you're using, but if those `Out[6]` and similar notations are referring to an actual list (that you can use to refer to previous outputs), then that's what's keeping your object alive. `del` just removes a *name*, it doesn't affect the object at all unless that name was the last remaining reference to it. – jasonharper Oct 06 '21 at 13:26
  • @jasonharper I edited the question for better reading. I get what you mean. But then `gc.collect()` should have removed the data created by `a` entirely. The snippet I show is all I typed in a freshly new python REPL (conda env). – deponovo Oct 06 '21 at 13:31
  • Your code works as expected if you put it in a file and run it with the `python` command, so there is no REPL involved. – Warren Weckesser Oct 06 '21 at 13:33
  • Tks, got it and pasted it as an answer for future ref. – deponovo Oct 06 '21 at 13:38
  • 1
    `del` does not delete objects. There is no way to manually delete an object in Python. `del a` unassigns the `a` variable. – user2357112 Oct 06 '21 at 13:41
  • That's ok. I was just not aware that the REPL is keeping the object alive even after calling `gc.collect()` since all var names pointing to `0x250f782f3a0` (in this case `a`) had been 'deleted' by me. – deponovo Oct 06 '21 at 13:43
  • 1
    An ordinary Python REPL would not have kept the object alive after the `gc.collect()`, but not because of any garbage collection effects - the object would have died because the last reference to the `A` instance was the magic `_` variable, and after the `gc.collect()`, the return value from `gc.collect()` would be assigned to that variable. – user2357112 Oct 06 '21 at 13:52
  • This is yet another interesting info. Tks – deponovo Oct 06 '21 at 16:41

1 Answers1

0

I tried what was mentioned in the comments to the question and am posting an answer for documentation purposes. Running the said code in the REPL was the problem.

What I tried:

test.py:

if __name__ == '__main__':
    import weakref, gc
    class A: pass
    a = A()
    b = weakref.ref(a)
    print("a: ", a)
    print("b(): ", b())
    del a
    print("b(): ", b())
    gc.collect()
    print("b(): ", b())

$ python test.py:

a:  <__main__.A object at 0x000002678F96A400>
b():  <__main__.A object at 0x000002678F96A400>
b():  None
b():  None

Process finished with exit code 0

So it does work as documented.

deponovo
  • 1,114
  • 7
  • 23