我有一个类,可以打开一个文件进行写入。在我的析构函数中,我调用了关闭文件的函数:
class MyClass:
def __del__(self):
self.close()
def close(self):
if self.__fileHandle__ is not None:
self.__fileHandle__.close()但是当我使用如下代码删除对象时:
myobj = MyClass()
myobj.open()
del myobj如果我试图重新实例化对象,我得到一个值错误:
ValueError: The file 'filename' is already opened. Please close it before reopening in write mode.但是,如果我在del myobj之前调用myobj.close(),我就不会遇到这个问题。那么为什么__del__()没有被调用呢?
发布于 2012-01-18 17:49:51
您确定要使用__del__吗?有带__del__的issues和垃圾收集。
您可以将MyClass设置为context manager:
class MyClass(object):
def __enter__(self):
return self
def __exit__(self,ext_type,exc_value,traceback):
if self.__fileHandle__ is not None:
self.__fileHandle__.close()通过这样做,您可以像这样使用MyClass:
with MyClass() as myobj:
...当Python离开with-block时,myobj.__exit__ (以及self.__fileHandle__.close())将被调用。
发布于 2012-01-18 17:49:33
这不是del所做的。不幸的是,__del__与del同名,因为它们彼此没有关系。在现代术语中,__del__方法将被称为终结器,而不是析构函数,区别很重要。
简短的区别是,很容易保证何时调用析构函数,但您几乎不能保证何时调用__del__,而且可能永远不会调用它。有许多不同的情况可以导致这种情况。
如果需要词法作用域,可以使用with语句。否则,请直接调用myobj.close()。del语句只删除引用,而不删除对象。
我找到了另一个问题的答案(link),它更详细地回答了这个问题。不幸的是,对这个问题的公认答案包含了严重的错误。
编辑:正如评论员所说,你需要从object继承。这很好,但仍然有可能永远不会调用__del__ (您可能会走运)。请参阅上面的链接答案。
发布于 2012-01-18 17:51:14
您的代码应该继承自object -至少六年来,不这样做已经被认为是过时的(除非在特殊情况下)。
你可以在这里阅读关于__del__的文章:http://docs.python.org/reference/datamodel.html#object.
简而言之,为什么需要继承object的原因是,__del__只对新样式的类具有“魔力”。
如果您需要依赖终结器的调用,我强烈建议您使用其他答案中推荐的上下文管理器方法,因为这是一个可移植的、健壮的解决方案。
https://stackoverflow.com/questions/8907905
复制相似问题