シャンクが彼の投稿を削除したので、私は__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への参照がないことが重要です。