gpt4 book ai didi

Python 静态变量列表 __del__

转载 作者:太空宇宙 更新时间:2023-11-03 13:45:41 32 4
gpt4 key购买 nike

我正在尝试使用静态列表创建一个类,它收集一个对象类的所有新实例。我面临的问题似乎是,一旦我尝试以与整数相同的方式使用列表,我就不能再使用魔法标记 __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

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

2
1

但是没有评论——包括现在的静态对象列表 MyClass.instances 我得到了错误的答案:

2
2

似乎 MyClass 无法访问它的 __del__ 方法了!怎么会?

最佳答案

来自docs ,

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.

当你取消评论时,

instances = []
...
...
MyClass.instances.append(self)

您正在 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]

我们可以调用每个 weakref 对象,而不是使用 remove 方法,如果它们返回 None,则它们已经死了。因此,我们使用列表理解将它们过滤掉。

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

关于Python 静态变量列表 __del__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21134946/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com