简体   繁体   中英

Delete an instance from its class' dict in desctructor?

I'm trying to create a class that saves all of its instances in a dictionary:

>>> class X:
    def __new__(cls, index):
        if index in cls._instances:
            return cls._instances[index]
        self = object.__new__(cls)
        self.index = index
        cls._instances[index] = self
        return self
    def __del__(self):
        del type(self)._instances[self.index]
    _instances = {}

However, the __del__ doesn't seem to work:

>>> x = X(1)
>>> del x
>>> X._instances
{1: <__main__.X object at 0x00000000035166D8>}
>>> 

What am I doing wrong?

Building on Kirk Strauser's answer, I'd like to point out that, when you del x , the class' _instances still holds another reference to x - and thus it can't be garbage collected (and __del__ won't run.

Instead of doing this kind of low-level magic, you probably should be using weakref s , which were implemented especially for this purpose.

WeakValueDictinary , in particular, suits your needs perfectly, and you can fill it on __init__ instead of fiddling with __new__ and __del__

You're not doing anything wrong, but __del__ isn't quite what you think. From the docs on it :

Note del x doesn't directly call x.__del__() — the former decrements the reference count for x by one, and the latter is only called when x 's reference count reaches zero.

Running this from the interpreter is particularly tricky because command history or other mechanisms may hold references to x for an indeterminate amount of time.

By the way, your code looks an awful lot like a defaultdict with X as the factory. It may be more straightforward to use something like that to be more explicit (ergo more Pythonic) about what you're trying to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM