在使用 OO Python 时,我遇到了以下好奇心。考虑以下简单的类:
>>> class Monty():
def __init__(self):
print 'start m'
def __del__(self):
print 'deleted m'
实例化对象按预期进行:
>>> a = Monty()
start m
>>> a
<__main__.Monty instance at 0x7fdf9f084830>
现在有趣的部分是:
>>> del a
>>> a = Monty()
start m
>>> a
deleted m
<__main__.Monty instance at 0x7fdf9f083fc8>
>>> a
<__main__.Monty instance at 0x7fdf9f083fc8>
>>> del a
>>> a = Monty()
start m
>>> del(a)
deleted m
>>> a = Monty()
start m
>>> a
deleted m
<__main__.Monty instance at 0x7fdf9f084830>
这里令人困惑的部分是我从析构函数中收到延迟的消息。我的理解是:
del a
删除对象引用,以便将对象 a 留给垃圾回收。但由于某种原因,解释器等待将消息传递到控制台。
另外这就是区别
del x
和
del(x)
因为如果您使用后者运行代码,则一切都会按预期进行 - 您可以从析构函数获得即时信息。
可以在 Python 2.7 以及使用 Python 3.3 上重现此内容。
最佳答案
Python 解释器创建一个附加引用。每次表达式不返回 None
时,结果都会被回显并存储在 _
内置名称中。
当您回显不同的结果时,_
会反弹到新结果,并且旧对象引用计数会下降。在您的情况下,这意味着只有这样才会收获前一个 Monty()
实例。
换句话说,当您执行del a
时,您并没有删除最后一个引用。只有当您稍后回显新对象时,最后一个引用才会消失:
>>> a = Monty() # reference count 1
start m
>>> a # _ reference added, count 2
<__main__.Monty instance at 0x7fdf9f084830>
>>> del a # reference count down to 1 again
>>> a = Monty()
start m
>>> a # _ now references the new object, count drops to 0
deleted m # so the old object is deleted.
<__main__.Monty instance at 0x7fdf9f083fc8>
您可以通过回显 _
来查看引用,并且可以通过回显完全不相关的内容来清除引用:
>>> a = Monty() # reference count 1
start m
>>> a # echoing, so _ is set and count is now 2
<__main__.Monty instance at 0x1056a2bd8>
>>> _ # see, _ is referencing the same object
<__main__.Monty instance at 0x1056a2bd8>
>>> del a # reference count down to 1
>>> _ # _ is still referencing the result
<__main__.Monty instance at 0x1056a2bd8>
>>> 'some other expression' # point to something else
deleted m # so reference count is down to 0
'some other expression'
>>> _
'some other expression'
del x 和 del(x) 之间没有区别。两者都执行 del
语句,括号是表达式的一部分,在这种情况下是无操作。没有 del()
函数。
真正的区别在于您没有在该代码部分中回显a
,因此没有创建额外的_
引用。
无论是否使用 (..)
括号,您都会得到完全相同的结果:
>>> a = Monty() # ref count 1
start m
>>> del a # no _ echo reference, so count back to 0
deleted m
>>> a = Monty() # ref count 1
start m
>>> del(a) # no _ echo reference, so count back to 0
deleted m
关于python - 奇怪的Python析构函数行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39280050/