python对象上可重复的id冲突

时间:2015-09-24 20:55:45

标签: python

我知道python builtin id()返回一个对象生命周期唯一的ID。我理解,具有非重叠生命期的对象最终可能具有相同的ID。但是,我试图理解这种相当混乱的行为:

>>> id(matplotlib.image.BboxImage.set_cmap)
4424372944
>>> id(numpy.ma.core.MaskedArray.sum)
4424372944

事实上,在多个解释器实例中,行为是可重复的:

Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)"
4343186208 4343186208
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)"
4521153312 4521153312
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)"
4358591264 4358591264
Mac:~$ python2.7 -c "import matplotlib.image; import numpy; print id(matplotlib.image.BboxImage.set_cmap), id(numpy.ma.core.MaskedArray.sum)"
4389970720 4389970720

matplotlib.image.BboxImage.set_cmapnumpy.ma.core.MaskedArray.sum似乎总是获得相同的ID,即使在python解释器的不同实例中也是如此。

现在我明白这与id()的文档一致,因为这两个对象在访问时是动态创建的,因此确实会有非重叠的生命周期。但是为什么这两个不相关的对象总是会使用相同的ID呢?

(这个问题与Object methods of same class have same id?不同,因为我在这里问为什么这在多个解释器实例中是可重复的,而不是简单地在具有非重叠生命周期的对象上进行虚假的id碰撞。)

1 个答案:

答案 0 :(得分:7)

任何实例方法都是如此,它是您正在测试的两个对象的类型。每次访问描述符时,都会实例化一个新的instancemethod对象。由于您没有保存对新创建的方法的引用,因此只要id返回就有资格进行垃圾回收,并且显然是在下次调用id之前收集它,所以同样内存位置可以重复使用。

可以通过另一种方式看到此行为:

>>> x = matplotlib.image.BboxImage.set_cmap
>>> y = matplotlib.image.BboxImage.set_cmap
>>> id(x) == id(y)
False

xy是对两个不同对象的引用,因为引用set_cmap每次都会创建一个新的instancemethod对象。