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

测试环境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
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值