You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不调用gc.collect()的情况下回收含绑定方法列表的对象

解决Python循环引用导致的对象无法自动回收问题

你的问题核心是绑定方法与实例形成了强循环引用,再加上类定义了__del__方法,Python的垃圾回收器无法自动处理带析构函数的循环引用,必须手动触发gc才能清理。以下是几种无需手动调用gc.collect()的解决方案:

方案1:存储非绑定方法,调用时手动传参

绑定方法self.print_func会隐式持有对实例self的引用,改成存储类的非绑定方法,打破循环:

class Foo():
    def __init__(self):
        self.functions = []
        print('CREATE', self)

    def some_func(self):
        # 存储类的非绑定方法,而非实例的绑定方法
        for i in range(3):
            self.functions.append(Foo.print_func)
        print(self.functions)

    def print_func(self):
        print('I\'m a test')

    def __del__(self):
        print('DELETE', self)

# 调用时需手动传入实例作为参数
# 示例:for func in self.functions: func(self)

方案2:用弱引用存储绑定方法

使用weakref模块创建绑定方法的弱引用,弱引用不会增加实例的引用计数,自然不会形成强循环:

import weakref

class Foo():
    def __init__(self):
        self.functions = []
        print('CREATE', self)

    def some_func(self):
        for i in range(3):
            # 创建绑定方法的弱引用
            weak_func = weakref.ref(self.print_func)
            self.functions.append(weak_func)
        print(self.functions)

    def print_func(self):
        print('I\'m a test')

    def __del__(self):
        print('DELETE', self)

# 调用时需先获取有效引用
# 示例:for func_ref in self.functions:
#         func = func_ref()
#         if func:
#             func()

方案3:移除__del__方法

如果业务场景允许,去掉__del__方法后,Python的垃圾回收器可以自动处理普通循环引用:

class Foo():
    def __init__(self):
        self.functions = []
        print('CREATE', self)

    def some_func(self):
        for i in range(3):
            self.functions.append(self.print_func)
        print(self.functions)

    def print_func(self):
        print('I\'m a test')

若需要跟踪对象销毁,可改用上下文管理器等替代方案,避免依赖__del__。

内容的提问来源于stack exchange,提问作者Ilya Palitsyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:30:04