我对以下代码的输出感到困惑,我在Ipython Notebook上运行:
class Point(object):
def __init(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "destroyed"
pt1 = Point()
pt2 = pt1
输出如下,在调用析构函数时我似乎无法理解: 点毁了
此外,当我编写下面的代码并期望得到错误时,我没有。
del pt1
del pt2
由于
编辑:我知道Python只在引用计数为0时调用_del_()
,但我不明白为什么在输出中编写以下结果:{{ 1}}。
Point destroyed
另外,鉴于上述情况,我知道pt1 = Point()
pt2 = pt1
或pt1
不存在,因此会在下面的代码中出现错误,但这种情况不会发生。
pt2
答案 0 :(得分:2)
我认为当多个变量指向同一个对象时,有一些关于引用计数的事情。请看下面的例子。
L1 = [1,2,3]
L2 = L1
现在让我们来看看id
s
>>> id(L1)
49127672
>>> id(L2)
49127672
因此,他们指向与预期相同的list
。
del L1
>>> L2
[1, 2, 3]
>>> id(L2)
49127672
L2
仍然存在且仍然具有相同的id
,即使L1
已被删除,也会首先创建该对象。
长话短说,我认为Python使用引用计数,并且在引用计数降为0之前实际上不会删除该对象。
关于您的修改
del pt1 # Reference count dropped from 2 to 1, __del__ is NOT called
del pt2 # Reference count dropped from 1 to 0, __del__ called
请注意,由于del pt2
而调用输出消息“Point destroyed”,因为pt1
不会调用此消息。
答案 1 :(得分:0)
如docs所说:
删除名称会删除该名称与本地名称空间或全局名称空间的绑定,具体取决于名称是否出现在同一代码块中的全局语句中。如果名称未绑定,则将引发NameError异常。
所以你只需从本地名称空间中删除两个条目,每个删除引用减少一个引用计数。只有在引用计数变为零后,才会调用__del__
。那不是C;)