python--为什么Python有相同的不可变对象id不同?

来源:互联网 发布:github php开源项目 编辑:程序博客网 时间:2024/06/05 23:07

测试环境Python 2.7.3 & python 3.6

小一点int类型相等
s = 1
r = 1 # id(s) == id(r) true
大一点的int类型就不一样了?
s = 1111111111
r = 11111111111 # id(s) != id(r)
所有测试的float类型都不相等
s = 1.1
r = 1.1
id(s) != id(r)
所有测试的tuple类型都不相等
s = (1, 2)
r = (1, 2)
id(s) != id(r)
所有测试的str都相等
s = ‘aaaa’
r = ‘aaaa’
id(s) == id(r)
不是应该都复用相同的不可变对象用以节约内存吗?

回答:

#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

作者:知乎用户
链接:https://www.zhihu.com/question/25050656/answer/34717037
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  int清楚写了[-5, 256] 这些小整数被定义在了这个对象池里.所以当引用小整数时会自动引用整数对象池里的对象的.  string对象也是不可变对象,python有个intern机制,简单说就是维护一个字典,这个字典维护已经创建字符串(key)和它的字符串对象的地址(value),每次创建字符串对象都会和这个字典比较,没有就创建,重复了就用指针进行引用就可以了. string实现了intern共享?我觉得是一种空间效率和时间效率的妥协。相比于数字,string本身参与的运算要少很多,而且string本身占据的空间也大许多,因此string的主要问题在于不共享带来的空间浪费,所以string实现了很费时间的intern操作。对于数字情况正好相反。作为一个数字,需要做的运算要比string多太多了,而且大小比string也小很多。如果在计算10000+20000之前先花好久查找重复对象,导致一个1ms完成的加法花了100ms,我肯定想砸电脑的。  float类型可以认为每个赋值都是创建一个对象,因为float有点多,所以没必要和int一样了.  tuple它是不可变对象,理应和int和string一样会做一个缓存,但是书上没有说明,于是看了看源码,发现tuple的数据结构很简单,简单到不能再简单,就是一个数组,里面是元组的迭代对象,这个对象指向的是各个元素.最关键的是元组没有实现intern机制!所以元组虽然是不可变对象,但它同时也是一个数组,这个数组和c里的数组一样,每次创建都会分配内存空间。

作者:五秋木
链接:http://www.jianshu.com/p/0f6f0db0ce8f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

原创粉丝点击