我有一个打开文件写作的类.在我的析构函数中,我调用关闭文件的函数:
class MyClass:
def __del__(self):
self.close()
def close(self):
if self.__fileHandle__ is not None:
self.__fileHandle__.close()
Run Code Online (Sandbox Code Playgroud)
但当我用以下代码删除对象时:
myobj = MyClass()
myobj.open()
del myobj
Run Code Online (Sandbox Code Playgroud)
如果我尝试重新实例化该对象,我会收到一个值错误:
ValueError: The file 'filename' is already opened. Please close it before reopening in write mode.
Run Code Online (Sandbox Code Playgroud)
而如果我myobj.close()之前打电话,del myobj我就不会遇到这个问题.那么为什么不__del__()被召唤?
那不是那个del.不幸的是,它们的__del__名称相同del,因为它们彼此无关.在现代术语中,该__del__方法将被称为终结器,而不是析构函数,并且差异很重要.
简单的区别在于,在调用析构函数时很容易保证,但是很少有关于何时__del__调用它的保证,它可能永远不会被调用.有许多不同的情况可以导致这种情况.
如果您需要词法作用域,请使用with语句.否则,myobj.close()直接打电话.该del语句仅删除引用,而不删除对象.
我找到了另一个答案(链接)到另一个问题,更详细地回答了这个问题.遗憾的是,该问题的公认答案包含了令人震惊的错误.
编辑:评论员指出,你需要继承object.这很好,但仍然有可能__del__永远不会被召唤(你可能会变得幸运).请参阅上面的链接答案.
你确定要使用__del__吗?有问题与__del__和垃圾收集.
您可以将MyClass设为上下文管理器:
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()
Run Code Online (Sandbox Code Playgroud)
通过这样做,您可以这样使用MyClass:
with MyClass() as myobj:
...
Run Code Online (Sandbox Code Playgroud)
并且myobj.__exit__(因而self.__fileHandle__.close())将在Python离开时调用with-block.
| 归档时间: |
|
| 查看次数: |
6188 次 |
| 最近记录: |