从析构函数中的 class' 字典中删除一个实例?

Delete an instance from its class' dict in desctructor?

我正在尝试创建一个 class 将其所有实例保存在字典中:

>>> 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>}
>>> 

我做错了什么?

基于 Kirk Strauser 的回答,我想指出的是,当您 del x 时,class' _instances 仍然持有 另一个 x 的引用 - 因此它不能被垃圾回收(并且 __del__ 不会 运行.

与其使用这种低级魔法,您可能应该使用 weakrefs,它是专门为此目的而实现的。

WeakValueDictinary,特别适合您的需求,您可以在 __init__ 上填写,而不是摆弄 __new____del__

你没有做错任何事,但 __del__ 与你想的不一样。来自 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.

运行 来自解释器的这个特别棘手,因为命令历史记录或其他机制可能会在不确定的时间内保存对 x 的引用。

顺便说一句,您的代码看起来非常像一个以 X 作为工厂的 defaultdict。使用类似的东西来更明确地(因此更 Pythonic)关于你正在尝试做的事情可能更直接。