如何删除闭包类中捕获的变量?附闭包与类闭包示例
闭包与“类闭包”的对象捕获示例
咱们来对比两个函数:一个返回普通闭包,另一个返回可当作闭包使用的类实例(也就是所谓的“类闭包”)。这里用weakref模块追踪创建的MyObject实例,两种场景下实例都会被闭包/类闭包捕获。
完整代码如下:
import weakref objects = {} # 用于追踪对象的弱引用 class MyObject(object): pass def leak1(): obj = MyObject() objects[id(obj)] = weakref.ref(obj) def inner(): return obj return inner def leak2(): obj = MyObject() objects[id(obj)] = weakref.ref(obj) class Inner(object): __slots__ = () def __call__(self): return obj return Inner()
核心细节拆解
- 在
leak1里,内部函数inner作为闭包捕获了外部作用域的obj,只要inner这个闭包对象还存在,obj就不会被垃圾回收 - 在
leak2里,动态创建的Inner类的__call__方法同样捕获了外部的obj,返回的Inner实例只要存活,obj也无法被回收 - 两种场景下,
objects字典里的弱引用都不会变为None,直到对应的闭包/类实例被销毁
内容的提问来源于stack exchange,提问作者C. Yduqoli
相关产品推荐
相关产品推荐

