Python静态变量列表__

2024-04-25 06:13:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用一个静态列表创建一个类,它收集一个对象类的所有新实例。我所面临的问题似乎是,只要我尝试使用一个与整数相同的列表,我就不能再使用神奇的标记__del__。在

我的例子:

class MyClass(object):  

    count = 0
    #instances = []

    def __init__(self, a, b):
        self.a = a
        self.b = b
        MyClass.count += 1
        #MyClass.instances.append(self)

    def __str__(self):
        return  self.__repr__()

    def __repr__(self):
        return "a: " + str(self.a) + ", b: " + str(self.b)

    def __del__(self):
        MyClass.count -= 1
        #MyClass.instances.remove(self)

A = MyClass(1,'abc')
B = MyClass(2,'def')
print MyClass.count
del B
print MyClass.count

通过评论,我得到了正确的答案:

^{pr2}$

但是没有注释-包括现在的静态对象列表MyClass.instances实例我得到了错误的答案:

2
2

我的类似乎不能再访问它的__del__方法了!怎么会?在


Tags: 对象instances实例答案self列表returndef
3条回答

{来自}

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. 

当你取消注释时

^{pr2}$

您正在MyClass.instances中存储对当前对象的引用。这意味着,引用计数在内部递增1。这就是为什么__del__没有立即被调用。在

若要解决此问题,请如下所示从列表中显式删除该项

MyClass.instances.remove(B)
del B

现在可以打印了

2
1

一如预期。在

还有一种方法可以解决这个问题。即使用weakref。从docs

A weak reference to an object is not enough to keep the object alive: when the only remaining references to a referent are weak references, garbage collection is free to destroy the referent and reuse its memory for something else. A primary use for weak references is to implement caches or mappings holding large objects, where it’s desired that a large object not be kept alive solely because it appears in a cache or mapping.

因此,拥有weakref不会推迟对象的删除。使用weakref,可以这样解决这个问题

MyClass.instances.append(weakref.ref(self))
...
...
# MyClass.instances.remove(weakref.ref(self))
MyClass.instances = [w_ref for w_ref in MyClass.instances if w_ref() is None]

{{{cd6>如果它们已经是

所以,现在,当你说del B,即使weakref是为B而存在的,它也会调用__del__(除非你让其他变量指向同一个对象,比如通过赋值)。在

__del__仅在没有剩余实例时调用。在

您应该考虑只将弱引用放入MyClass.instances列表中。在

这可以通过import weakref来实现,然后

  • 或者对列表使用WeakSet
  • 或者将weakref.ref(self)放入列表中。在

每当删除最后一个“strict”引用时,__del__将被自动调用。那些懦夫会自动消失。在

但是请注意,docs中提到的__del__有一些注意事项。在

From to http://docs.python.org/2.7/reference/datamodel.html#basic-customization我引用(段落object.__del__后灰色):

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.

在这里您调用del B,但是在中仍然有一个B的实例MyClass.instances实例,因此B仍然被引用,因此不会被销毁,因此不会调用__del__函数。 如果您直接调用B.__del__(),它就可以工作了。在

相关问题 更多 >