引用相同位置的python类实例

时间:2012-12-23 13:45:06

标签: python

我有一个名为Door的班级和一个名为Window的班级。它是名为Furniture的类的子类。我的程序读取excel文件,循环2次,第一次读/写关于门的一切,第二次关于窗口。简化,我有以下代码:

for gathering_inf in ('door', 'window'):
    for row in file:
        if gathering_inf == 'door' and currently reading door line:
            furniture = Door(width, height, description)
        if gatherig_inf == 'window' and currently reading window line:
            furniture = Window(width, height, description)

        # Now do something with the furniture object ..

奇怪的想法发生的是,如果我(例如上图所示)打印对象furniture,我得到它们的位置,并且内存中的一些对象的位置是相同的,即使它们是两个不同实例宽度不同的属性。例如:

<__main__.Door object at 0x03BFE810>
<__main__.Door object at 0x03BFE890>
<__main__.Door object at 0x03BFE810>
<__main__.Door object at 0x03BFE890>
<__main__.Door object at 0x03BFE8B0>
<__main__.Door object at 0x03BFE8D0>
<__main__.Door object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE8D0>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>
<__main__.Window object at 0x03BFE8B0>
<__main__.Window object at 0x03BFE890>

有人可以向我解释为什么python会这样做吗?

2 个答案:

答案 0 :(得分:4)

这是因为引用计数垃圾收集器。只要将新对象分配给furniture,GC就会删除该对象,因此新对象可以重新使用其内存位置。


这是一个显示此行为的小型演示。请注意,由于Python REPL的工作方式(它保留对_中最后一个结果的引用),地址将交替。

>>> foo = object(); foo
<object object at 0x7fd74cd390a0>
>>> foo = object(); foo
<object object at 0x7fd74cd390b0>
>>> foo = object(); foo
<object object at 0x7fd74cd390a0>
>>> foo = object(); foo
<object object at 0x7fd74cd390b0>
>>> foo = object(); foo
<object object at 0x7fd74cd390a0>

答案 1 :(得分:1)

ThiefMaster几乎把它钉了出来:这就是Python虚拟机的工作方式。

您正在观察的是引用计数垃圾收集器 CPython 实现的细节。在你的情况下, CPython 是垃圾收集Door对象,然后创建一个新的Window对象,然后重用(现在垃圾收集)Door对象的位置,将Window对象存储在那里。

实际上看到 CPython 重用以前垃圾回收的对象的地址是很常见的。 例如,在我的计算机上运行ThiefMaster的代码我得到了稍微不同(旋转)的结果:

CPython memory usage

此时请务必注意此行为是CPython特定的。例如,Enthought's Python Distribution似乎没有产生类似的结果,但我不知道这种不一致是否与实现差异有关:

enter image description here