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 callx.__del__()
— the former decrements the reference count forx
by one, and the latter is only called whenx
'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.