关于 python 的整数在内存的疑问

2015-07-17 17:53:50 +08:00
 aragakiiyui
我装的是32位的python2.7.9的python,然后发现1~256这个范围的数字的内存是共享,比如我:
a = 1 # id(a) = 31341232
b = 1 # id(b) = 31341232
c = 1 # id(c) = 31341232
他们的id是一样的,

但是一旦数字超过了256,
e = 257 #id(e) = 40104988
f = 257 #id(f) = 40104940
他们的id是不同的。按理说,id不同才比较复合预期,所以我想问,为什么会出现上述id相同的情况,是不是有什么机制啊?!求解~
2876 次点击
所在节点    Python
11 条回复
echo1937
2015-07-17 17:59:54 +08:00
学python的时候没有接触"可变对象""不可变对象""引用计数"这样的概念吗?

你看的都什么出版社的书啊.
aragakiiyui
2015-07-17 18:06:33 +08:00
@echo1937 数字是不可变对象吧,而且引用计数不是针对可变对象么?!
11
2015-07-17 18:07:39 +08:00
@echo1937 呵呵。
11
2015-07-17 18:07:58 +08:00
@aragakiiyui 回答你的问题:
https://docs.python.org/2/c-api/int.html#c.PyInt_FromLong

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)
bearzk
2015-07-17 18:09:23 +08:00
https://docs.python.org/2/c-api/int.html
```
PyObject* PyInt_FromLong(long ival)
Return value: New reference.
Create a new integer object with a value of ival.

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)
```

文档说是-5 ~ 256都是存好的, 可能是为了快吧.
lzjun
2015-07-17 18:09:41 +08:00
[-5, 256]这些小对象由于使用频率高,python把他们缓存在内存中
aragakiiyui
2015-07-17 18:21:45 +08:00
@11 @bearzk @lzjun 理解了~~谢谢
luobuda
2015-07-17 21:03:53 +08:00
Cpython代码

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS 257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS 5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
can be shared.
The integers that are saved are those in the range
-NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif

small_ints就是小整数缓存 05~256
可以修改重新编译
BUPTGuo
2015-07-17 21:09:21 +08:00
Java也有类似的策略,恩
mingyun
2015-07-18 09:56:31 +08:00
@lzjun 原来
aheadlead
2015-07-18 23:01:07 +08:00
@echo1937 希望还是尽量说一些能解决问题的话…

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/206442

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX