我知道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_cmap
和numpy.ma.core.MaskedArray.sum
似乎总是获得相同的ID,即使在python解释器的不同实例中也是如此。
现在我明白这与id()
的文档一致,因为这两个对象在访问时是动态创建的,因此确实会有非重叠的生命周期。但是为什么这两个不相关的对象总是会使用相同的ID呢?
(这个问题与Object methods of same class have same id?不同,因为我在这里问为什么这在多个解释器实例中是可重复的,而不是简单地在具有非重叠生命周期的对象上进行虚假的id碰撞。)
答案 0 :(得分:7)
任何实例方法都是如此,它是您正在测试的两个对象的类型。每次访问描述符时,都会实例化一个新的instancemethod
对象。由于您没有保存对新创建的方法的引用,因此只要id
返回就有资格进行垃圾回收,并且显然是在下次调用id
之前收集它,所以同样内存位置可以重复使用。
可以通过另一种方式看到此行为:
>>> x = matplotlib.image.BboxImage.set_cmap
>>> y = matplotlib.image.BboxImage.set_cmap
>>> id(x) == id(y)
False
x
和y
是对两个不同对象的引用,因为引用set_cmap
每次都会创建一个新的instancemethod
对象。