欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

python 小数据内存池

is 和 == 的区别

今天探讨了is和==的区别,发现python中一些基本数据类型有存在专有数据池,数据池是python对内存的做的一些优化机制。

我们先看下is和逻辑操作符==的区别

== 是判断两边对象的值是否一样,返回bool类型

is 判断两边对象的内存地址是否一样,返回bool类型

In [1]: a = 1000
In [2]: b = 1000
In [3]: a == b
Out[3]: True
In [4]: a is b
Out[4]: False
In [5]: id(a)
Out[5]: 1502151552848
In [6]: id(b)
Out[6]: 1502151552528

可以发现,判断两个值,如果 is 判断得到的是True, == 得到的结果肯定是True,但 == 得到的结果是True,is判断可就不一定了。

下面我们说下小数据池的概念(只适用于数字和字符串)

在一定的范围内使用,值相同的数字共用相同的内存地址。

整数字范围-5~256 之间的数字,数值相同的对象都是共用内存地址的。

这个范围~5-256 可以理解为小整数据池。

还有一个特点是,如果对象属于小数据池中的数据,当对象被销毁,python只会将这个对象引用回收掉,然而内存数据还是存在的,当由其他对象引用到该值时,会发现新的对象的内存地址跟之前销毁的内存地址是一样的。

为了避免因创建相同的值而重复申请内存空间所带来的效率问题, Python解释器会在启动时创建出小整数池,范围是[-5,256],该范围内的小整数对象是全局解释器范围内被重复使用,永远不会被GC回收
In [29]: a = 100 
In [30]: id(a) Out[30]: 1548187760 In [31]: del a In [32]: b = 100 In [33]: id(b) Out[33]: 1548187760 新的引用对象和已经销毁的引用对象的内存地址是一样的。 In [35]: c = 1000 In [36]: id(c) Out[36]: 2405167166768 In [37]: del c In [38]: d = 1000 In [39]: id(d) Out[39]: 2405167166512

 

In [1]: a = -5
In [2]: b = -5
In [3]: id(a)
Out[3]: 1548184400  # -5 共用内存地址,直接指向小数据池
In [4]: id(b)
Out[4]: 1548184400
In [5]: c = 256
In [6]: d = 256
In [7]: id(c)
Out[7]: 1548192752  # 256 共用内存地址,直接指向小数据池
In [8]: id(d)
Out[8]: 1548192752
In [9]: e = -6
In [10]: f = -6
In [11]: id(e)
Out[11]: 2405167166288  # -6 超出小数据池范围,重新给分配内存地址
In [12]: id(f)
Out[12]: 2405167166448
In [13]: g = 257
In [14]: h = 257
In [15]: id(g)
Out[15]: 2405167169104
In [16]: id(h)
Out[16]: 2405167166544

 

字符串驻留

当两段完全相同的字符串,python会让他们共用同一段内存,这种我们就称之为字符串驻留,但是字符串的内容也是有限制的,只允许由数字字母及下划线组成的字符串才符合字符串驻留的规则。

python默认只会对由字符
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"构成字符串进行intern。

In [40]: a = "helloworld"
In [41]: id(a)
Out[41]: 2405167500016
In [42]: b = "helloworld"
In [43]: id(b)
Out[43]: 2405167500016
In [44]: c = "hello world"  #字符串含有 " " 不符合驻留规则,
In [45]: id(c)
Out[45]: 2405166197168
In [46]: d = "hello world"
In [47]: id(d)
Out[47]: 2405168198512
In [48]: e = "hello_world"
In [49]: f = "hello_world"
In [50]: id(e)
Out[50]: 2405167500784
In [51]: id(f)
Out[51]: 2405167500784
In [52]: g = "hello_world!" #字符串含有 "!" 不符合驻留规则
In [53]: h = "hello_world!"
In [54]: id(g)
Out[54]: 2405168200816
In [55]: id(h)
Out[55]: 2405167481904

字符串驻留的时机

字符串只会在编译的时候驻留,而不是在运行时

In [1]: a = "hello"

In [2]: b = "world"

In [3]: "hello" + "world" is "helloworld"
Out[3]: True

In [4]: a+b is "helloworld"
Out[4]: False

更详细关于python小数据池的问题可以跳到这里:

https://www.cnblogs.com/tielemao/p/8652105.html

 

posted on 2018-08-02 15:23  Louiszj  阅读(1022)  评论(0编辑  收藏  举报

导航