首页 > 解决方案 > 垃圾回收完成后的方法调用

问题描述

我有一个类“Foo”,其中对象注册在一个名为 FooManager 的对象中。离开函数的范围后,只有当我知道所有“标记为删除”的 Foo 时,才能删除 Foo 对象。

class FooManager:
    
    def __init__(self):
        self.deletion_list = []
    
    def delete_tagged_foos(self):
        #Deletion process
        pass

class Foo:

    def __init__(self, FooManager):
        self.FooManager = FooManager

    def __del__(self):
        self.FooManager.deletion_list.append(self)

        if garbage_collection_finished():
            self.FooManager.delete_tagged_foos()


def foo_processing(manager):
    foo1 = Foo(manager)
    foo2 = Foo(manager)
    foo3 = Foo(manager)
    
    # Tag foo2 and foo3 for deletion (but not foo1)
    # and perform deletion process once every foo is tagged
    return foo1


manager = FooManager()

foo1 = foo_processing(manager)

我怎样才能获得布尔garbage_collection_finished()?

标签: pythongarbage-collectiondestructorreference-counting

解决方案


如何在 FooManager 中跟踪 foo 实例并将其用作创建临时 foo 实例的函数的装饰器:

import sys

class FooManager:
    
    def __init__(self):
        self.foos = []

    def registerFoo(self,foo):
        foo.FooManager = self
        self.foos.append(foo)
        print("+1")

    def cleanFoos(self,func):
        def callFunc(*args,**kwargs):
            result = func(*args,**kwargs)
            # 3 refs = self.foos, foo in comprehension, getrefcount param
            orphanFoos = [foo for foo in self.foos if sys.getrefcount(foo)<=3]
            # process orphans as needed
            # leave them in self.foos if they are not to be deleted
            self.foos  = [foo for foo in self.foos if foo not in orphanFoos]
            # ...
            print("foo count:",len(self.foos))
            return result 
        return callFunc
        
class Foo:

    def __init__(self, FooManager):
        FooManager.registerFoo(self)

    def __del__(self): print("deleted")

用法:

manager = FooManager()

@manager.cleanFoos
def foo_processing(manager):
    foo1 = Foo(manager)
    foo2 = Foo(manager)
    foo3 = Foo(manager)
    
    # Tag foo2 and foo3 for deletion (but not foo1)
    # and perform deletion process once every foo is tagged
    return foo1

foo1 = foo_processing(manager)

输出:

+1
+1
+1
foo count: 1
deleted
deleted

推荐阅读