我需要在实例被删除时进行对象清理,但不在退出时。实例可以自我删除吗?
我想在运行时删除一个实例时做一些清理工作,但不想在程序退出时进行的垃圾回收时做这些清理。
在下面的例子中,当 c 被删除时,会有一个文件被删除,这正是我想要的;但是,当程序退出时,这个文件也会被删除,这不是我想要的。
class C:
def __del__(self):
os.remove(self.filename)
c=C()
del c
我可以把运行时实例的删除和一段代码关联起来,但在 Python 退出时不执行那段代码吗?
谢谢。
2 个回答
1
你想做的事情在Python中不是很常见(我觉得这可能不太可能实现)。在程序运行时删除实例通常是不必要的。
你可以在运行时用自己的函数来代替 del
:
def rem(object):
object.__remove()
class C:
def __remove(self):
os.remove(self.filename)
c=C()
rem(c)
或者你可以把删除功能作为实例的方法来实现(这样更符合Python的风格!):
class C:
def remove(self):
os.remove(self.filename)
c=C()
c.remove()
或者你可以在程序结束时销毁删除处理器:
class C:
instances = []
def __init__(self):
C.instances.append(self)
def __del__(self):
C.instances.remove(self)
os.remove(self.filename)
c = C()
del c
# ... do something ...
for c in C.instances:
del c.__del__
4
CPython 使用引用计数的方式来管理内存,只有在特定情况下才会运行一个完整的垃圾回收(GC),这个垃圾回收可以处理循环引用。比如,当你执行 c = C(); del c
时,新的 C
对象会立即被垃圾回收处理。至于 __del__
方法和解释器退出时的情况,文档中提到:
并不能保证在解释器退出时,仍然存在的对象的
__del__()
方法会被调用。
不过,这种情况似乎很难确定。此外(虽然这在实际中关系不大),其他实现,比如 Jython 和 IronPython,并不使用引用计数,这意味着对象的销毁和清理就不那么可预测了(理论上,在 .NET 中可能根本不会发生)。
总之,这个要求(只有在正常的垃圾回收时才执行 __del__
,而不是在解释器退出时)听起来有点奇怪。你能详细说明一下为什么需要关注这个问题吗?
你可能会想要使用一个 上下文管理器。