Search code examples
pythongarbage-collectionjupyter-notebookglobal-variables

Unexplained variables in global namespace


I'm finding that if I don't assign the returned value of a function to variable, it still ends up in the global namespace. To re-create the situation in miniature, I've created a test class, and a function that returns an instance of that class:

class testclass:
    def __init__(self):
        pass

def test_func():
    return testclass()

I've then created a function to count how many of these variables are in the global namespace:

def count_tc(glob):
    num = 0
    for name, obj in glob.items():
        if isinstance(obj, testclass):
            print(name)
            num+=1
    return num

if I run this count_tc function initially, it returns 0. But if I run test_func then re-run it, I get:

test_func()
count_tc(globals())

Returning

_
_8
2

So we now have not one but two variables in the global namespace that seem to have been assigned _ type names.

My understanding of the garbage collection process in python is that if there are no references to an object, it gets deleted - so I'd expect that to happen in this case. This is a toy example but I have it going on somewhere else where memory is an issue and it seems to be creating problems. Could anyone enlighten me as to what is (or what is meant to be) happening here? I'm not sure if this is relevant but I'm running this in Jupyter notebook. Thanks!


Solution

  • See https://ipython.readthedocs.io/en/stable/interactive/tutorial.html#history

    Basically, Ipython automatically captures the object returned by your test_func() invocation thus increasing its ref count. The GC works as you expect. Which is why you don't see the testclass instance being kept around when you run the code via a normal python interpreter.