我正在处理一个外部库,它不以Python方式处理其资源。该库本质上是一个 C++ 库,周围有一个 Python 包装器。每当库函数返回 C++ 对象时,我实际上得到的是它的字符串句柄。对象本身会保留在内存中,直到我以该句柄作为参数显式调用 delete()
函数。我尝试在句柄周围引入我自己的包装器,以确保当包装器超出范围时将其删除。像这样的事情:
#import some_module as sm
class MyWrapper(str):
def __new__(*args, **kwargs):
# do something
def __del__(self):
sm.delete(self)
这在大多数情况下都有效,但在脚本完成时,我经常收到一个异常,提示 sm
没有属性 delete
。看起来模块对象在我的句柄周围的包装器之前就被销毁了。有没有办法确保在卸载模块之前调用我的 __del__
?
最佳答案
解释器关闭可能会以任意顺序清除模块。通过将任何所需的清理函数绑定(bind)为默认值,将它们本地存储在__del__
中:
class MyWrapper(str):
def __new__(*args, **kwargs):
# do something
def __del__(self, _delete=sm.delete):
_delete(self)
由于默认值是在定义上绑定(bind)的,并且在函数本身被删除之前一直保留,因此只要函数/方法存在,_delete
就会保持原始 sm.delete
可用。
请注意,__del__
可以在任意时间调用,包括从不调用。通常最好将其用作最后的手段:提供其他方式来显式释放对象(例如支持 with
或 .close()
/.delete()
方法)并以这样的方式编写 __del__
:如果对象已经被释放,则它不执行任何操作。
关于python - 引用外部资源时正确使用 __del__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67742862/