Python';内存中低值整数的布局

Python';内存中低值整数的布局,python,memory,Python,Memory,我的问题是:这些模式(如下)起源于哪里 我(在某处)了解到,Python对于小整数有唯一的“拷贝”(如果这个词正确的话)。例如: >>> x = y = 0 >>> id(0) 4297074752 >>> id(x) 4297074752 >>> id(y) 4297074752 >>> x += 1 >>> id(x) 4297074728 >>> y 0 当我查看

我的问题是:这些模式(如下)起源于哪里

我(在某处)了解到,Python对于小整数有唯一的“拷贝”(如果这个词正确的话)。例如:

>>> x = y = 0
>>> id(0)
4297074752
>>> id(x)
4297074752
>>> id(y)
4297074752
>>> x += 1
>>> id(x)
4297074728
>>> y
0
当我查看int的内存位置时,有一个简单的模式:

>>> N = id(0)
>>> for i in range(5):
...     print i, N - id(i)
... 
0 0
1 24
2 48
3 72
4 96
>>> bin(24)
'0b11000'
我不清楚为什么选择这个作为增量。此外,我无法解释256以上的模式:

>>> prev = 0
>>> for i in range(270):
...     t = (id(i-1), id(i))
...     diff = t[0] - t[1]
...     if diff != prev:
...         print i-1, i, t, diff
...         prev = diff
... 
-1 0 (4297074776, 4297074752) 24
35 36 (4297073912, 4297075864) -1952
36 37 (4297075864, 4297075840) 24
76 77 (4297074904, 4297076856) -1952
77 78 (4297076856, 4297076832) 24
117 118 (4297075896, 4297077848) -1952
118 119 (4297077848, 4297077824) 24
158 159 (4297076888, 4297078840) -1952
159 160 (4297078840, 4297078816) 24
199 200 (4297077880, 4297079832) -1952
200 201 (4297079832, 4297079808) 24
240 241 (4297078872, 4297080824) -1952
241 242 (4297080824, 4297080800) 24
256 257 (4297080464, 4297155264) -74800
257 258 (4297155072, 4297155288) -216
259 260 (4297155072, 4297155336) -264
260 261 (4297155048, 4297155432) -384
261 262 (4297155024, 4297155456) -432
262 263 (4297380280, 4297155384) 224896
263 264 (4297155000, 4297155240) -240
264 265 (4297155072, 4297155216) -144
266 267 (4297155072, 4297155168) -96
267 268 (4297155024, 4297155144) -120

有什么想法,线索,可以找的地方吗

编辑:24小时有什么特别的吗

更新:该标准具有
sys.getsizeof()
,当我以
1
作为参数调用它时,它返回
24
。这是很多字节,但在64位机器上,类型、值和引用计数各有8个字节。另外,请参见和C API参考

在评论中与Peter Hansen链接中的“来源”联系了一段时间。找不到int的定义(除了声明
*int\u int
),但我确实找到了:

#define NSMALLPOSINTS       257
#define NSMALLNEGINTS       5

在CPython中,前256个整数是预先分配的

>>> for n in range(1000):
>>>  if id(n) != id(n+0):
>>>   print n
>>>   break

257

低值整数是预先分配的,高值整数在计算时分配。源代码中出现的整数是同一个对象。在我的系统中

>>> id(2) == id(1+1)
True
>>> id(1000) == id(1000+0)
False
>>> id(1000) == id(1000)
True
您还将注意到,ID取决于系统。它们只是内存地址,由系统分配器(或者可能是静态对象的链接器)分配


编辑:之所以
id(1000)==id(1000)
,是因为Python编译器注意到它编译的代码中有两个整数常量是相同的,所以它只为这两个常量分配一个对象。这在运行时将是一个不可接受的性能损失,但在编译时它并不明显。(是的,解释器也是一个编译器。大多数解释器也是编译器,很少有解释器不是。)

最多256个整数被插入,这就是为什么你会在那里看到一个“模式”。所有其他整数都是在执行过程中创建的,因此分配给random
id

我似乎记得Python在内部缓存int<256的副本,以避免为常用情况创建新的Python对象。因此,一旦超过256个,每次都会得到新创建的对象,这些对象可能会“随机”地排列在内存中(显然,它们的位置对Python的分配器来说是有意义的,但对我们来说可能没有意义)。

因为其他人已经完全回答了为什么ID具有高达256个的独特模式,我想我应该回答你的补遗:24是python中整数对象的字节大小。分配前256个整数时,它们在内存中连续分配,导致每个内存地址之间相差24。

“有什么想法、线索、要查找的地方吗?”是的。阅读来源。它会告诉你你想知道的一切。是的,但是源代码像C或者其他东西我希望有一个与政治公众人物(PEP)相当的人。政治公众人物(PEP)不会指定这样的实施细节。如果你想知道这样的东西,它实际上不会影响(正常的)代码,它将出现在源代码中。不是在PEP中,也不是在源代码中:(注意它的值是从-5到256)。哦,也请参阅OK。“random”或其他任何值,大于256。具体来说(并且仅限于当前),它的值从-5到256。最好在回答中解释为什么
id(1000)
案例返回True。(这是一件只有在向你解释过之后才合理地显而易见的事情。)
>>> id(0)
8402324