欢迎访问Python每天3分钟系列。

图片

每天花3分钟时间,学习或温习一个Python知识点。今天是第041篇:

常量池

昨天讲3个很有用的函数(dir, help和id)的时候,有下面这段代码:

>>> name = '张三'
>>> name2 = '张三'
>>> name3 = '张三'
>>> id(name)
4347189392
>>> id(name2)
4347194288
>>> id(name3)
4348257232

例子中虽然三个变量都是张三,但它们的内存地址是不同的,说明它们不是同一个对象。

非常勤奋好学的麦友@薛定谔的猫提出了问题:

“为什么name=“张三”,name,name2,name3地址不一样。name=”rick”,name,name2,name3地址就是一样的呀?

我们试一下:

>>> name1 = 'rick'
>>> name2 = 'rick'
>>> name3 = 'rick'
>>> id(name1)
4312573040
>>> id(name2)
4312573040
>>> id(name3)
4312573040

真的是一样的啊!

再试试maishu,也是一样的:

>>> name1 = 'maishu'
>>> name2 = 'maishu'
>>> name3 = 'maishu'
>>> id(name1)
4304891312
>>> id(name2)
4304891312
>>> id(name3)
4304891312

如果换成中文的麦叔呢?

>>> name1 = '麦叔'
>>> name2 = '麦叔'
>>> name3 = '麦叔'
>>> id(name1)
4304625968
>>> id(name2)
4304629808
>>> id(name3)
4304630096

如果字符串是中文的麦叔,3个对象就是独立的对象,地址不同。

这就引入了今天的知识点:常量池

以下面这段代码为例,解释常量池的概念:

>>> name1 = 'maishu'
>>> name2 = 'maishu'
>>> name3 = 'maishu'
>>> id(name1)
4304891312
>>> id(name2)
4304891312
>>> id(name3)
4304891312
  • 第一次创建字符串maishu,Python在内存中创建一个新的对象。因为这个对象是个不可变对象,Python会把这对象放在一个池子中,叫做常量池。
  • 第二次创建字符串maishu的时候,Python解释器会去池子里看一下这个字符串是否已经存在,如果存在了就不再重复创建,而是直接使用它。节省内存,提高效率。
  • 第三次同理。

如果是这样,那为什么字符串麦叔就不行了呢?这是歧视麦叔吗?

原因是这个池子的容量必须是有限的,否则效果会适得其反,浪费内存,浪费时间。

假设这个池子无限大,里面放了几百万个对象,为了创建一个简单的字符串麦叔,需要先在几百万个对象中查找是否存在。那还不如直接创建快呢!

所以Python的常量池中只会存放少量的对象,具体规则不同的Python解释器实现有所不同,但一般来说只包括ASCII码所组成的字符串。所以中文字符串明显就不会进入常量池了。

除了字符串,数字也是一样的,看一个进入常量池的例子:

>>> a = 87
>>> b = 87
>>> id(a)
4303162288
>>> id(b)
4303162288

两个87对象是同一个内存地址,87进入了常量池。

看看这个,998就没有进入常量池,这是因为数字的常量池一般只包括0到256之间的,大于256就不会进入常量池了。

>>> a = 998
>>> b = 998
>>> id(a)
4312629360
>>> id(b)
4312629392

总结一下:

  • Python为了提高效率,会把一些不可变对象放入常量池,重复利用,节省内存,节约时间。
  • 不同的Python解释器会有不同的实现,这里的重点是知道这个原理,具体规则要看解释器本身。
声明:本网站资源来源于网络收集,如有侵权,请联系站长进行删除处理。 分享目的仅供大家学习和交流,请不要用于商业用途,否则后果自负。本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解。本站资源售价只是赞助,收取费用仅维持本站的日常运营所需。反馈邮箱:1159995880@qq.com