我试图创建一个将所有实例保存在字典中的类:
>>> 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 = {}
但是,__del__
似乎无效:
>>> x = X(1)
>>> del x
>>> X._instances
{1: <__main__.X object at 0x00000000035166D8>}
>>>
我做错了什么?
答案 0 :(得分:2)
根据Kirk Strauser的回答,我想指出,当您del x
时,“_instances
”类仍然保留对x
的另一个引用 - - 因此它不能被垃圾收集(并且__del__
将无法运行。
你可能应该使用weakref
s,而不是做这种低级魔术,而WeakValueDictinary专门用于此目的。
{{3}},尤其适合您的需求,您可以在__init__
上填写,而不是摆弄__new__
和__del__
答案 1 :(得分:1)
你没有做错任何事,但__del__
并不是你的想法。来自the docs on it:
注意
del x
不直接调用x.__del__()
- 前者将x
的引用计数减1,后者仅在x
时调用{1}}的引用计数达到零。
从解释器运行它特别棘手,因为命令历史记录或其他机制可能会在不确定的时间内保留对x
的引用。
顺便说一下,你的代码看起来非常像一个X
作为工厂的默认代码。使用类似的东西更直接(更多Pythonic)可能会更直接地了解你正在尝试做的事情。