为什么id(id)和id(id(id))总是返回相同的值,而id(id(id(id)))"循环"超过3个值?

时间:2014-08-14 23:08:17

标签: python python-2.7

发生在python 2.7.8上。 3.4.1不会发生。

示例:

>>> id(id)
140117478913736
>>> id(id)
140117478913736
>>> id(id)
140117478913736
>>> id(id(id))
38775176
>>> id(id(id))
38775176
>>> id(id(id))
38775176
>>> id(id(id(id)))
38775152
>>> id(id(id(id)))
38775224
>>> id(id(id(id)))
38775176

...等。最后一行总是返回这三个值,循环遍历它们。

5“id”:始终是相同的值。

6“id”:循环三个值。

2 个答案:

答案 0 :(得分:4)

id()的结果保证在您传入的对象的持续时间内相同。

因此,只要参数id(id)存在,id就会产生相同的结果。这是永远的。

但是,id(id(id))只会产生相同的结果,只要id(id)的结果存在,但此对象只是临时的。它可以巧合多次返回相同的结果,但你不能依赖这种行为。我可以证明:

>>> id(id(id))
12345
>>> id(id(id))
12345 # coincidence!
>>> [1, 2, 3]
[1, 2, 3]
>>> id(id(id))
98765 # now it's different!

所以,你所看到的只是Python实现中分配模式的巧合。

为什么要循环三个?

在你的Python中,我猜这种情况正在发生。左边是正在评估的表达式,右边是堆。

id(id(id))          [ ]
id(140117478913736) [ 140117478913736 ]           # evaluate
38775176            [ 140117478913736, 38775176 ] # evaluate
                    [ _ , 38775176 ]              # decref

id(id(id))          [ _ , 38775176 ]
id(140117478913736) [ 140117478913736, 38775176 ] # evaluate

你可以看到id(id(id)),每个对象占据堆中的第一个槽,因为id(id)总是进入同一个槽,你总是得到相同的结果......除非你分配一些东西!

答案 1 :(得分:0)

id(id)必须在单个执行实例中保持不变,因为id不是某个临时对象。

任何其他带有嵌套id调用字符串的表达式实际上并不需要具有一致的结果,因为您试图得到某个整数的id,其生命周期结束于整个表达式被计算,id恰好是文档提到的对象的内存地址。这是一个实现细节,所以你不应该指望它。但是,这个细节是你获得这些结果的原因。

事实上,它在Python 3.4.1中没有发生,只是告诉你这些动态对象的内存分配和释放模式是不同的。这不重要。这些信息对您没有任何帮助。

重要的是id为所有具有有效生命周期的对象保证唯一标识符。有关此标识符含义的详细信息与程序员无关。