了解Python中的内存分配

时间:2014-10-01 20:34:10

标签: python

我对以下代码的输出感到困惑,我在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

2 个答案:

答案 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;)