Python弱引用finalize机制与资源自动清理
请详解weakref.finalize的机制和使用场景。与__del__方法相比有什么优势?finalize在对象被GC时自动执行清理函数,如何处理清理函数中可能出现的异常?如何实现临时文件自动删除和数据库连接自动释放?atexit和finalize的配合使用。
回答
小字辈
weakref.finalize:在对象被垃圾回收时自动执行回调(对象生命周期终结时)。
import weakref, tempfile, os
class TempFile:
def __init__(self):
self.f = tempfile.NamedTemporaryFile(delete=False)
weakref.finalize(self, self._cleanup, self.f.name)
@staticmethod
def _cleanup(name):
try:
os.unlink(name)
except FileNotFoundError:
pass
vs __del__:
| 特性 | __del__ | finalize |
|------|-----------|------------|
| 确定性 | 低(调用时机不确定) | 高(对象回收时立即执行) |
| 异常处理 | 异常默认被压制 | 可控制异常行为 |
| 循环引用 | Python 3.4+可处理 | 正常处理 |
| 参数 | 仅self | 任意参数 |
| 优先级 | 与GC交互复杂 | 简单可靠 |
数据库连接自动释放:
class DBConnection:
def __init__(self, conn):
self.conn = conn
weakref.finalize(self, self._close, conn)
@staticmethod
def _close(conn):
conn.close()
与atexit配合:
import atexit
class Resource:
def __init__(self):
self._finalizer = weakref.finalize(self, self._cleanup)
atexit.register(self._finalizer) # 程序退出时也清理
注意:finalize创建的引用是弱引用,不会阻止对象被GC。回调以LRU顺序执行。可通过detach()取消注册。