我知道__del__Python类的功能并未像许多人期望的那样被视为析构函数。
__del__
我还理解,还有更多的“ pythonic”和可以说是更优雅的方式来进行整理,特别是使用with结构。
但是,当编写可能不熟悉python方式的读者使用的代码时,当清理很重要时,是否有一种优雅的方法可以使我__del__可靠地充当析构函数,而又不干扰python的自然使用__del__?
__del__表现为破坏者的期望似乎并 不合理 ,同时也很普遍。因此,我只是想知道是否有一种优雅的方法来使它按预期运行- 忽略了关于pythonic的优缺点可能引起的众多争论。
如果您了解所有这些内容,为什么不以Pythonic的方式来做呢?比较另一个需要清除的类:tempfile.TemporaryDirectory。
tempfile.TemporaryDirectory
with TemporaryDirectory() as tmp: # ... # tmp is deleted def foo(): tmp = TemporaryDirectory() foo() # tmp is deleted
他们如何做到这一点?这是相关的位:
import weakref class Foo(): def __init__(self, name): self.name = name self._finalizer = weakref.finalize(self, self._cleanup, self.name) print("%s reporting for duty!" % name) @classmethod def _cleanup(cls, name): print("%s feels forgotten! Bye!" % name) def cleanup(self): if self._finalizer.detach(): print("%s told to go away! Bye!" % self.name) def foo(): print("Calling Arnold") tmpfoo = Foo("Arnold") print("Finishing with Arnold") foo() # => Calling Arnold # => Arnold reporting for duty # => Finishing with Arnold # => Arnold feels forgotten. Bye! def bar(): print("Calling Rocky") tmpbar = Foo("Rocky") tmpbar.cleanup() print("Finishing with Rocky") bar() # => Calling Rocky # => Rocky reporting for duty! # => Rocky told to go away! Bye! # => Finishing with Rocky
weakref.finalize将_cleanup在对象被垃圾回收时触发,或者在程序结束时(如果它仍在周围)触发。我们可以保留finalizer,以便可以明确杀死对象(使用detach)并将其标记为死对象,以便不调用finalizer(当我们要手动处理清理操作时)。
weakref.finalize
_cleanup
detach
如果您想使用来支持上下文用法with,那么添加__enter__和__exit__方法是很简单的,只需调用cleanupin __exit__(如上所述的“手动清理”)即可。
with
__enter__
__exit__
cleanup