当调用具有相等值的可变对象的标识时,会出现以下模式。
如您所见,id(mutObj)
返回的值并不完全独立于id(mutObj)
的先前返回值,但模式不稳定。
这种行为对于Python代码本身来说可能是无关紧要的,但是我对了解底层机制非常感兴趣!
>>> id([1,2])
6706248
>>> id([1,2])
59597256
>>> id([1,2])
56866632
>>> id([1,2])
56866632
>>> id([1,2])
56881992
>>> id([1,2])
56881992
>>> id([1,2])
56879624
>>> id([1,2])
56867784
>>> id([1,2])
56867784
>>> id([1,2])
56879624
在win32上Python 3.4.3 [MSC v.1600 64位(AMD64)]
请注意,最后一个值等于之前返回的三个调用值。
答案 0 :(得分:1)
Python对您创建的所有对象使用相同的id
:
>>> for x in range(10):
print(id([1, 2]))
4479841736
4479841736
4479841736
4479841736
4479841736
4479841736
4479841736
4479841736
4479841736
4479841736
由于没有对创建列表的引用,因此将立即对其进行垃圾回收,并重新使用id
。
将列表分配给名称obj
,将使列表保持活动状态,直到将新列表分配给同一名称:
>>> for x in range(10):
obj = [1, 2]
print(id(obj))
4486925128
4486925192
4486925128
4486925192
4486925128
4486925192
4486925128
4486925192
4486925128
4486925192
在第二次迭代中,obj
存在且obj = [1, 2]
在分配给obj
之前先创建新列表。分配后,旧列表将被垃圾收集,id
再次可用以重复使用。每次迭代都重复此操作。
当您将列表中的引用保留到所有创建的列表时:
>>> objs = []
>>> for x in range(10):
obj = [1, 2]
print(id(obj))
objs.append(obj)
4480011848
4483963144
4486916488
4486914376
4486914568
4486916616
4486914824
4486915016
4486915272
4486915464
Python必须为所有这些使用不同的id
。
在标准的交互式提示符(Python 3.5.1)中工作,我可以产生这个:
>>> id([1, 2])
4330529608
>>> id([1, 2])
4330529608
>>> id([1, 2])
4330529608
>>> id([1, 2])
4330529608
>>> id([1, 2])
4330529608
>>> id([1, 2])
4330529608
但是在IPython或IPython Notebook中工作,你得到了这个:
In [1]: id([1, 2])
Out[1]: 4359684552
In [2]: id([1, 2])
Out[2]: 4379935816
In [3]: id([1, 2])
Out[3]: 4373482696
In [4]: id([1, 2])
Out[4]: 4359674248
In [5]: id([1, 2])
Out[5]: 4373482696
这是因为IPython在后台做了一些工作,并创建了在创建新对象之前重用已释放id
的对象。
答案 1 :(得分:1)
引自the docs(强调我的):
的id
强>(
object
)
返回对象的“标识”。这是一个整数,保证是唯一且恒定的 这个对象在其生命周期中。 两个非重叠的对象 生命周期可能具有相同的
id()
值。CPython实现细节:这是对象的地址 存储器强>
基本上,当您编写id([1, 2])
时,您创建一个列表,检查其id
,并将其丢弃,这使其有资格进行垃圾回收。在CPython中,由于通过引用计数进行垃圾收集,它会被删除,并且没有任何禁止在内存中完全相同的位置创建另一个对象,因此具有相同的id
。