python - 在 Python 中 : How to remove an object from a list if it is only referenced in that list?

标签 python list object reference garbage-collection

我想跟踪当前正在使用的某种类型的对象。例如:跟踪一个类的所有实例或由元类创建的所有类。

很容易跟踪这样的实例:

class A():
    instances = []
    def __init__(self):
        self.instances.append(self)

但是,如果一个实例在该列表之外的任何地方都没有被引用,那么它就不再需要了,我不想在一个可能耗时的循环中处理该实例。

我尝试使用 sys.getrefcount 删除仅在列表中引用的对象。

for i in A.instances:
    if sys.getrefcount(i) <=3: # in the list, in the loop and in getrefcount
        # collect and remove after the loop

我遇到的问题是引用计数非常模糊。 打开一个新的 shell 并创建一个没有内容的虚拟类返回 5 for

sys.getrefcount(DummyClass)

另一个想法是复制对象,然后删除列表并检查哪些对象已安排进行垃圾收集,并在最后一步删除这些对象。像这样的东西:

Copy = copy(A.instances)
del A.instances
A.instances = [i for i in Copy if not copy_of_i_is_in_GC(i)]

当引用计数变为 0 时,不必立即删除对象。我只是不想在不再使用的对象上浪费太多资源。

最佳答案

这个答案与 Kevin 的答案相同,但我正在编写一个带有弱引用的示例实现,并将其发布在这里。使用弱引用解决了对象被 self.instance 列表引用的问题,因此它永远不会被删除。

为对象创建弱引用的其中一件事是您可以在删除对象时包含回调。存在诸如程序退出时未发生回调等问题...但这可能正是您想要的。

import threading
import weakref

class A(object):
    instances = []
    lock = threading.RLock()

    @classmethod
    def _cleanup_ref(cls, ref):
        print('cleanup') # debug
        with cls.lock:
            try:
                cls.instances.remove(ref)
            except ValueError:
                pass

    def __init__(self):
        with self.lock:
            self.instances.append(weakref.ref(self, self._cleanup_ref))

# test
test = [A() for _ in range(3)]
for i in range(3,-1,-1):
    assert len(A.instances) == i
    if test:
        test.pop()

print("see if 3 are removed at exit")
test = [A() for _ in range(3)]

关于python - 在 Python 中 : How to remove an object from a list if it is only referenced in that list?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37232884/

相关文章:

python - Python 的键盘中断不会中止 Rust 功能(PyO3)

python - 使用 .join() 和列表理解将前缀连接到列表中的每个单词

javascript - 这在 js "xin || {}"中有什么作用?

Python:如何从两个模块导入具有相同名称的类?

python - 如何忽略 Pyglet 窗口中的 UI 缩放?

python - 如何使用可变长度序列的序列拆包?

list - SwiftUI - 两个独立的按钮合二为一

java - 当 Web 应用程序被多个用户使用时,普通的旧 Java 对象会发生什么情况?

JavaScript - 始终访问特定对象的最佳方式

python - Tensorflow:特定GPU设备下的dynamic_rnn无法工作,没有GPU设备支持的内核可用