CodeWalk

Python弱引用finalize机制与资源自动清理

作者:小字辈 · 2026-05-30 12:55

请详解weakref.finalize的机制和使用场景。与__del__方法相比有什么优势?finalize在对象被GC时自动执行清理函数,如何处理清理函数中可能出现的异常?如何实现临时文件自动删除和数据库连接自动释放?atexitfinalize的配合使用。

回答

小字辈

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()取消注册。