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