既然shanked删了他的贴子,我再表态__del__
:
import atexit, weakref
class Handler:
def __init__(self, obj):
self.obj = weakref.ref(obj)
def cleanup(self):
if self.obj is not None:
obj = self.obj()
if obj is not None:
obj.cleanup()
class Foo:
def __init__(self):
self.start()
def cleanup(self):
print "cleanup"
self.cleanup_handler = None
def start(self):
self.cleanup_handler = Handler(self)
atexit.register(self.cleanup_handler.cleanup)
def end(self):
if self.cleanup_handler is None:
return
self.cleanup_handler.obj = None
self.cleanup()
def __del__(self):
self.end()
a1=Foo()
a1.end()
a1=Foo()
a2=Foo()
del a2
a3=Foo()
a3.m=a3
这支持以下情况:
- 定期调用 .end 的对象;马上清理
- 在没有调用 .end 的情况下释放的对象;最后一个引用消失时的清理
- 生活在循环中的物体;清理 atexit
- 保持活力的物体;清理 atexit
请注意,清理处理程序持有对对象的弱引用很重要,否则它会使对象保持活动状态。
编辑:涉及 Foo 的循环不会被垃圾收集,因为 Foo 实现了__del__
. 为了允许在垃圾收集时删除循环,必须将清理从循环中取出。
class Cleanup:
cleaned = False
def cleanup(self):
if self.cleaned:
return
print "cleanup"
self.cleaned = True
def __del__(self):
self.cleanup()
class Foo:
def __init__(self):...
def start(self):
self.cleaner = Cleanup()
atexit.register(Handler(self).cleanup)
def cleanup(self):
self.cleaner.cleanup()
def end(self):
self.cleanup()
Cleanup 对象没有对 Foo 的引用,这一点很重要。