测试环境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];#endif1234567891011121314

作者:知乎用户 
链接: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 
來源:简书 
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。