为什么较大的int数字返回不同,有时相同的id?

时间:2017-01-27 01:22:45

标签: python python-3.x

今天我了解了id,并决定将其用于测试。我知道整数是不可变的,所以id应该是(?)相同的。但是当我在提示中测试时,我注意到了细微的差异,并想找出背后的原因。

a = 1
id(a)    # 10055552
id(1)    # 10055552
a = int(1)
id(a)    # 10055552

酷!所有检查到目前为止。但是......然后......

a = 10000
id(a)           # 140230117375888
id(10000)       # 140230116779920
a = int(10000)
id(a)           # 140230116779920

# wait what?? try it again
id(10000)       # 140230116780080
# Huh!?

好的,所以测试一下,我注意到这种行为发生在256.ID最多可达8位数,然后257会返回15位长的较大ID。所以int类型必须是8个字节。测试一下:

a = 256
id(a)     # 10063712
id(256)   # 10063712

a = 257
id(a)     # 140230116780080
id(257)   # 140230117375888
a = int(257)
id(a)     # 140230117375888
id(257)   # 140230116779920

所以我发现它与8字节长有关,但任何大于256的东西都会重用一些相同的ID:

140230116780080
140230116780048
140230116780144
140230117375888
140230116779920

请注意以上列表并非详尽无遗。

引擎盖下发生了什么?为什么有些ID会被重复使用?测试多个变量:

a = 257
b = 258
c = 259

id(a)      # 140230116780176
id(257)    # 140230116779984   <--- reused?
id(b)      # 140230116780080
id(258)    # 140230116780144
id(c)      # 140230116780048
id(259)    # 140230116779984   <--- reused?

id(257) == id(259)    # False

TL; DR - 对于256以上的整数,为什么有些id会被重用?我认为这些id在他们的一生中应该是独一无二的,但是其中一些看起来相同但是在比较它们时它们是不同的?请查看最后提供的示例。

另外,为什么有少数id被用于这些较大的整数?对于使用更多变量的系统,这可能有所不同吗?

在Python 3.4.3,Linux上的GCC 4.8.4上测试过。

1 个答案:

答案 0 :(得分:2)

作为优化,Python预先创建了一系列int对象(我认为它默认为-5 ... 256,这是一个编译时选项),并且总是优先使用这些对象来创建新的int 。对于超出该范围的整数,再次需要完全相同的int的可能性被认为太低而不值得检查所需的int对象是否已经存在。

这是一个实施细节。如果您的代码真的关心它,那么您正在做一些可怕的错误。