在分配相同的值时,为什么不为元组获取相同的ID?

时间:2018-03-16 19:03:07

标签: python tuples immutability python-internals

当我执行以下步骤时,即使我重新分配较旧的值(a),两个元组(b(1,2))也都不会保留其原始ID。

>>> a , b = (1,2) , (1,2)
>>> a
(1, 2)
>>> b
(1, 2)
>>> id(a) , id(b)
(80131912, 91541064)
>>> a , b = (3,4) , (3,4)
>>> a
(3, 4)
>>> b
(3, 4)
>>> id(a) , id(b)
(91559048, 91689032)
>>> a , b = (1,2) , (1,2)
>>> a
(1, 2)
>>> b
(1, 2)
>>> id(a) , id(b)
(91556616, 91550408)

但是在下面的例子中,两者都得到了旧ID。

>>> a = (1,2)
>>> b = (1,2)
>>> a , b
((1, 2), (1, 2))
>>> id(a)
88264264
>>> id(b)
88283400
>>> a = (3,4)
>>> b = (3,4)
>>> id(a)
88280008
>>> id(b)
88264328
>>> a = (1,2)
>>> b = (1,2)
>>> id(a)
88264264
>>> id(b)
88283400
>>> a , b
((1, 2), (1, 2))
>>> id(a) , id(b)
(88264264, 88283400)

有人可以解释一下吗?

1 个答案:

答案 0 :(得分:5)

您创建了新的元组对象。它们具有相同的内容并不意味着它们将成为内存中完全相同的元组对象。

不变性并不意味着创建相同的将创建相同的对象。你永远不会改变旧的(1, 2)元组,你的新(1, 2)元组也不可变。

CPython确实保留了可重复使用的元组对象的缓存(因此它不必一直创建新对象,Python在典型程序中经历了很多小元组),但是这样做了。一个你不能依赖的实施细节。对于长度为2的元组,正是这个缓存是再次看到相同ID的原因。如果您想了解缓存的实现方式,请参阅How is tuple implemented in CPython?

此外,在CPython中,id()是对象的内存位置,一旦释放旧对象,Python就可以自由地重用内存位置。这是clearly documented

  

这是一个整数,在该生命周期内,该对象保证唯一且恒定。具有非重叠生存期的两个对象可能具有相同的id()值。

始终可以看到新对象的id()值。有时这意味着你仍然拥有相同的对象(如小整数或元组或某些类型的字符串对象的情况),有时只是解释器在内存中重复使用相同的位置。您永远不应该依赖于此,这些是用于性能目的的实现细节,并且可能会发生变化。