Python之常量池

Posted 朝阳区靓仔_James

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python之常量池相关的知识,希望对你有一定的参考价值。

常量池

有下面这段代码:

>>> 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 = 'chanping'
>>> name2 = 'chanping'
>>> name3 = 'chanping'
>>> id(name1)
4304891312
>>> id(name2)
4304891312
>>> id(name3)
4304891312
  • 第一次创建字符串chanping,Python在内存中创建一个新的对象。因为这个对象是个不可变对象,Python会把这对象放在一个池子中,叫做常量池。
  • 第二次创建字符串chanping的时候,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解释器会有不同的实现,这里的重点是知道这个原理,具体规则要看解释器本身。

推荐阅读

表弟说,这个Python定时任务,能挣五千,问我信吗?

以上是关于Python之常量池的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程案例之线程池

python基础之小数据池

Python之常量池

JAVA-初步认识-常用对象API(String类-常见功能-intern方法)

如何优雅的使用和理解线程池----转

线程池与Python中的GIL