如何强制删除Python对象?
我很好奇Python中__del__
的细节,何时、为什么应该使用它以及它不应该用于什么。我经历了惨痛的教训才知道,它并不像人们天真地期望的析构函数那样,因为它不是 __new__
/ __init__
的反面。
class Foo(object):
def __init__(self):
self.bar = None
def open(self):
if self.bar != 'open':
print 'opening the bar'
self.bar = 'open'
def close(self):
if self.bar != 'closed':
print 'closing the bar'
self.bar = 'close'
def __del__(self):
self.close()
if __name__ == '__main__':
foo = Foo()
foo.open()
del foo
import gc
gc.collect()
我在文档中看到,不能保证为解释器退出时仍然存在的对象调用 __del__()
方法。
- 如何保证对于解释器退出时存在的任何
Foo
实例,该栏已关闭? - 在上面的代码片段中,栏是在
del foo
上还是在gc.collect()
上关闭的...还是两者都没有?如果您想更好地控制这些细节(例如,当对象未被引用时,应该关闭栏),通常的实现方法是什么? - 当
__del__
被调用时,是否保证__init__
已经被调用?如果 __init__ 引发怎么办?
I am curious about the details of __del__
in python, when and why it should be used and what it shouldn't be used for. I've learned the hard way that it is not really like what one would naively expected from a destructor, in that it is not the opposite of __new__
/ __init__
.
class Foo(object):
def __init__(self):
self.bar = None
def open(self):
if self.bar != 'open':
print 'opening the bar'
self.bar = 'open'
def close(self):
if self.bar != 'closed':
print 'closing the bar'
self.bar = 'close'
def __del__(self):
self.close()
if __name__ == '__main__':
foo = Foo()
foo.open()
del foo
import gc
gc.collect()
I saw in the documentation that it is not guaranteed __del__()
methods are called for objects that still exist when the interpreter exits.
- how can it be guaranteed that for any
Foo
instances existing when the interpreter exits, the bar is closed? - in the code snippet above does the bar get closed on
del foo
or ongc.collect()
... or neither? if you want finer control of those details (e.g. the bar should be closed when the object is unreferenced) what is the usual way to implement that? - when
__del__
is called is it guaranteed that__init__
has already been called? what about if the__init__
raised?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
关闭资源的方法是上下文管理器,又名
with
语句:输出:
2) Python 的对象在引用计数为 0 时被删除。在您的示例中,
del foo
删除最后一个引用,因此立即调用 __del__ 。 GC 不参与此事。输出:
gc
与删除您和大多数其他对象无关。当简单的引用计数由于自引用或循环引用而不起作用时,它会在那里进行清理:输出:
3)让我们看看:
给出:
对象是用
__new__
创建的,然后传递给__init__
作为自我
。在__init__
中发生异常后,该对象通常不会有名称(即f =
部分不运行),因此它们的引用计数为0。这意味着对象被正常删除并调用__del__
。The way to close resources are context managers, aka the
with
statement:output:
2) Python's objects get deleted when their reference count is 0. In your example the
del foo
removes the last reference so__del__
is called instantly. The GC has no part in this.output:
The
gc
has nothing to do with deleting your and most other objects. It's there to clean up when simple reference counting does not work, because of self-references or circular references:output:
3) Lets see:
gives:
Objects are created with
__new__
then passed to__init__
asself
. After a exception in__init__
, the object will typically not have a name (ie thef =
part isn't run) so their ref count is 0. This means that the object is deleted normally and__del__
is called.一般来说,为了确保无论如何都会发生某些事情,
无论
try
块中是否有错误,以及是否有错误,您使用的finally
块都会运行。是except
块中发生的任何错误处理中的错误。如果您不处理引发的异常,则在执行finally
块后仍会引发该异常。确保文件关闭的一般方法是使用“上下文管理器”。
http://docs.python.org/reference/datamodel.html#context-managers
这将自动关闭
f
。对于您的问题#2,当引用计数达到零时,
bar
会立即关闭,如果没有其他引用,则del foo
会立即关闭。对象不是由
__init__
创建的,而是由__new__
创建的。http://docs.python.org/reference/datamodel.html#object.< strong>new
当你执行
foo = Foo()
时,实际上发生了两件事,首先创建了一个新对象,__new__
,然后它正在初始化,__init__
。因此,在这两个步骤发生之前,您不可能调用del foo
。然而,如果__init__
中出现错误,__del__
仍然会被调用,因为该对象实际上已经在__new__
中创建了。编辑:如果引用计数减少到零,则在删除发生时进行更正。
In general, to make sure something happens no matter what, you use
finally
blocks will be run whether or not there is an error in thetry
block, and whether or not there is an error in any error handling that takes place inexcept
blocks. If you don't handle an exception that is raised, it will still be raised after thefinally
block is excecuted.The general way to make sure a file is closed is to use a "context manager".
http://docs.python.org/reference/datamodel.html#context-managers
This will automatically close
f
.For your question #2,
bar
gets closed on immediately when it's reference count reaches zero, so ondel foo
if there are no other references.Objects are NOT created by
__init__
, they're created by__new__
.http://docs.python.org/reference/datamodel.html#object.new
When you do
foo = Foo()
two things are actually happening, first a new object is being created,__new__
, then it is being initialized,__init__
. So there is no way you could possibly calldel foo
before both those steps have taken place. However, if there is an error in__init__
,__del__
will still be called because the object was actually already created in__new__
.Edit: Corrected when deletion happens if a reference count decreases to zero.
也许您正在寻找上下文管理器?
Perhaps you are looking for a context manager?
__del__()
将被调用。这可能是GC引起的。__init__()
引发异常,则假定该对象不完整,并且__del__()
将不会被调用。__del__()
gets called when the number of references to an object hits 0 while the VM is still running. This may be caused by the GC.__init__()
raises an exception then the object is assumed to be incomplete and__del__()
won't be invoked.