首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Python中:如果一个对象只在列表中被引用,如何从该列表中删除该对象?

在Python中:如果一个对象只在列表中被引用,如何从该列表中删除该对象?
EN

Stack Overflow用户
提问于 2016-05-15 07:21:09
回答 3查看 3.3K关注 0票数 17

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

很容易跟踪这样的实例:

代码语言:javascript
复制
class A():
    instances = []
    def __init__(self):
        self.instances.append(self)

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

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

代码语言:javascript
复制
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

代码语言:javascript
复制
sys.getrefcount(DummyClass)

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

代码语言:javascript
复制
Copy = copy(A.instances)
del A.instances
A.instances = [i for i in Copy if not copy_of_i_is_in_GC(i)]

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-05-15 08:38:49

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

为对象创建弱引用的一件事是,当对象被删除时,您可以包括回调。有一些问题,比如程序退出时不会发生回调...但这可能就是你想要的。

代码语言:javascript
复制
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)]
票数 7
EN

Stack Overflow用户

发布于 2016-05-15 07:59:31

解决这个问题的标准方法是通过weak references。基本思想是保留对象的弱引用列表,而不是对象本身,并定期从列表中删除已死的弱引用。

对于字典和集合,有一些更抽象的类型,比如weakref.WeakKeyDictionary(),当你想把弱引用放在更复杂的地方时,比如字典的键。这些类型不需要手动修剪。

票数 7
EN

Stack Overflow用户

发布于 2016-05-15 07:42:20

试试gc.get_referrers(obj)吧。The gc module Documentation

代码语言:javascript
复制
len(gc.get_referrers(my_obj))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37232884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档