1

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

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

我究竟做错了什么?

4

2 回答 2

2

在 Kirk Strauser 的回答的基础上,我想指出,当你 时del x,类'_instances仍然持有另一个引用x- 因此它不能被垃圾收集(并且__del__不会运行。

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

特别是WeakValueDictinary非常适合您的需求,您可以填写它__init__而不是摆弄__new__and__del__

于 2015-03-21T16:07:57.467 回答
1

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.

于 2015-03-21T16:08:33.260 回答