0

Here's my problem. I fire up a fresh python console and I type in the following:

import gc
meeseeks_instance = False

class Meeseeks(object):
    def __init__(self):
        gc.collect()
        print('Look at me!')

    def __del__(self):
        print('Mission accomplished!')
        globals()['meeseks_instance'] = False

    def __new__(cls):
        gc.collect()
        if globals()['meeseeks_instance']:
            raise Exception('Theres already a Meeseeks!')
        globals()['meeseeks_instance'] = True
        return super().__new__(cls)

Now, if I type:

>>> mymeeseeks = Meeseeks()
Look at me!
>>> del mymeeseeks
Mission accomplished!

Fantastic. Now:

>>> Meeseeks()
Look at me!
<Meeseeks object at 0x043DE290>

The object was not assigned, so it's not reachable and it should be garbag collected; anyways, it seems that garbage collection was not yet run. But, if I force it, the object is correctly collected:

>>> gc.collect()
Mission accomplished!
0

And here starts the trouble. If I try to instantiate two Meeseeks, the explicit garbage collection in __new__ does not fire and the Exception is raised:

>>> Meeseeks()
Look at me!
<Meeseeks object at 0x043B0990>
>>> Meeseeks()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 18, in __new__
Exception: Theres already a Meeseeks!

Why does this happen? How can I make so that trying to instantiate a new Meeseeks forces garbage collection of the previous, unreachable Meeseeks?

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Lester Jack
  • 179
  • 8
  • 1
    It's still reachable, through the `_` variable. There's probably a good dupe target somewhere around here. – user2357112 Jun 20 '18 at 18:08
  • 1
    You really shouldn't rely on the first `Meeseeks` instance to be garbage collected before you instantiate the 2nd one anyway. You should make it obvious and explicit when the instance is no longer needed - i.e. you should use a context manager. – Aran-Fey Jun 20 '18 at 18:12

1 Answers1

0

You made a typo of meeseks_instance in __del__, but furthermore, I think the default behavior of python's garbage collection already works as you wish.

>>> class Meeseeks(object):
...     def __init__(self):
...         print('Initiating %s' % self)
...     def __del__(self):
...         print('Deleting %s' % self)
...
>>> Meeseeks();Meeseeks()
Initiating <__main__.Meeseeks object at 0x00E88C70>
<__main__.Meeseeks object at 0x00E88C70>
Initiating <__main__.Meeseeks object at 0x00ECA1D0>
Deleting <__main__.Meeseeks object at 0x00E88C70>
<__main__.Meeseeks object at 0x00ECA1D0>
blhsing
  • 91,368
  • 6
  • 71
  • 106