is用于判断两个对象是否为同一个对象,具体来说是两个对象在内存中的位置是否相同。

python为了提高效率,节省内存,在实现上大量使用了缓冲池技术和字符串intern技术。

整数和字符串是不可变对象,也就意味着可以用来共享,如100个“python”字串变量可以共享一个“python”字符串对象,而不是创建100个“python”字符串。

一、小整数对象池

为了应对小整数的频繁使用,python使用对小整数进行了缓存,默认范围为[-5,256],在这个范围内的所有整数被python完全地缓存,当有变量使用这些小整数时,增加对应小整数对象的引用即可。

由上面的实例可以看到,当变量在[-5,256]之间时,两个值相同的变量事实上会引用到同一个小整数对象上,也就是小整数对象池中的对象,而不会去创建两个对象。而当变量超出了这个范围,两个值相同的变量也会各自创建整数对象,所以两者对应的对象不同。

二、字符串intern

如果当前变量引用的字符串对象已经存在的话,直接增加对应字符串对象的引用,而不去创建新的字符串对象,这就是字符串intern机制。

说白了,intern机制就是每创建一个比较短的字符串对象,就在一个叫interned的字典里面查看是否存在字符串相同的字符串对象,如果存在的话,就把字典存放的对象的ob_refcnt加1,然后销毁新创建的对象,所以才会出现下面的情景 a is b的结果为True:

1. 奇怪的现象

在详细探讨字符串intern机制之前,先看一个奇怪的问题:

直接在交互式IPython中运行:

i is j的结果是False。

定义一个函数并运行:

输出结果:

True

上述代码分开运行,结果为False,但是合在一起结果却为True。也就是说分开运行的时候,i和j指向不同对象,而合在一起的时候i,j却指向了相同对象。为了明白其中的缘由,需要简单理解python的编译机制。

三、编译机制

在python中,万物皆对象,包括代码本身也是一种对象。python用code对象表示代码,代码编译后产生code对象。通常一个作用域对应一个code对象。

1. 编译结果

上述代码中编译生成了两个code对象,一个代表全局作用域,另一个代表函数f。

code对象保存了变量,常量(常量字面量)以及编译结果。code对象用常量表来保存常量,考虑到一个常量可能出现多次,在一张表上保存一个常量多次太过于奢侈。所以code对象对每个常量只保存一次,在需要引用它的地方使用它在常量表的位置作为常量的表示。在上述编译结果中可以看到,"1 2"这个字符串常量使用了两次,编译的代码为"LOAD_CONST 0",这里的0就是"1 2"在常量表当中的位置。

由于编译的这个特性,在同一个code对象 中的变量,如果它们引用了同一个常量,那么无论这个常量有没有缓冲机制,它们引用的都是同一个对象。

2. 案例理解

输出结果:

True True True True

字符串对象除了intern机制以外,还有类似于小整数对象的字符缓冲池,其实就是用一个类似于数组的东西(characters array)指向这个对象,对只有一个字符的字符串,第一次创建时候会进行如下操作:

1.创建对象

2.对其进行intern操作

3.将对象放进字符缓冲池

那么下次再创建这个字符对象时候,会首先查看字符缓冲池中是否存在这个对象,如果存在的话,返回这个缓冲对象。区别于小整数对象的是,小整数对象在python解释器初始化之初就创建了,而字符串缓冲池指向的对象直到用到的时候才会创建。

四、编译机制与小整数对象池对比

i和j引用同一个常量,这是编译机制,所以i与j指向同一个整数对象,后面a和b虽然相等,但不引用常量,此时启用小整数对象池,a和b都等于256,在对象池中,所以a,b引用同一个对象,后面c和d不在对象池中,所以两者对象不同。

这里有一点需要注意,没有变量参与的运算会被编译器直接优化成对应的常量,进而保存进常量表中。

五、字符串intern机制与字符缓冲池

在编译过程中,字符串intern机制将所有的变量名进行intern,但对常量进行的intern有一点特殊的限制。能够intern的常量必须只包含[a-zA-Z0-9_],即字母数字加下划线,如果含有其他字符,就不会intern。在运行过程中,通过计算得到的字符串不会intern。

字符串有一个和小整数对象池相似的字符缓冲池,用于在运行过程中缓存单个字符,所以计算得到的字符串虽然不会intern,但如果是单个字符,就会使用到字符缓冲池。

可以看到,a和b确实指向同一个对象,而c和d指向不同对象,这就是字符缓冲池。

六、编译机制与字符串intern对比

i包含空格,包含空格的常量不会被intern,而其他两个常量不包含其他字符,所以会被intern。

七、总结python代码被编译成code对象,通常一个code对象对应于一个作用域,作用域中重复出现的变量名以及常量在code中只保存一次。

字符串intern机制主要作用于编译过程,在编译收集完变量和常量时,对变量和常量进行intern,而后构建一个code对象。

字符串intern对常量的intern有限制,能够intern的常量必须只包含[a-zA-Z0-9_],即字母数字加下划线,如果含有其他字符,就不会intern。

小整数对象池和字符缓冲池都是作用于运行过程中,python缓存小的整数和字符,当有变量使用这些对象时,不用额外创建对象。

python字符串常量有什么区别_Python经典面试题:is与==的区别相关推荐

  1. python中bytearray和java中byte[]的区别_Python经典面试题:说说Python中xrange和range的区别?...

    昨晚一小伙后台问xrange和range有啥区别,讲了下他倒领悟的挺快,其实这也是你各面试Python岗位,经常会遇到的Python面试题,长个心眼哈,说不定明年3月你找工作就用上了. 废话不多说,开 ...

  2. python字符串常量_常用的Python字符串常量

    原博文 2013-09-21 22:28 − 下面是一些常用的Python字符串常量string.digits:包含0-9的字符串string.letters:包含所有大小写字母的字符串 string ...

  3. java接口和抽象类的区别(经典面试题)

    java接口和抽象类的区别(经典面试题) 要了解接口和抽象类的区别,首先需要明白接口和抽象类的定义. 1.抽象类 包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可 ...

  4. python字符串常量_python教程---字符串常量ascii_letters、punctuation、digits、whitespace等...

    字符串常量 此模块中定义的常量为: string.ascii_letters 下文所述 ascii_lowercase 和 ascii_uppercase 常量的拼连. 该值不依赖于语言区域. str ...

  5. python sorted函数_Python 经典面试题 二

    1.简要描述Python的垃圾回收机制(garbage collection) Python中的垃圾回收是以引用计数为主,标记-清除和分代收集为辅. •引用计数:Python在内存中存储每个对象的引用 ...

  6. python字符串倒数第三个_python字符串常用方法

    python 字符串常用操作方法 python 字符串操作常用操作,如字符串的替换.删除.截取.赋值.连接.比较.查找.分割等 1.去除空格 str.strip():删除字符串两边的指定字符,括号的写 ...

  7. python字符串函数的find方法_python字符串的方法与操作大全

    一:字符串的方法与操作 *注意:首字母为l的为从左边操作,为r的方法为从右边操作 1.__contains__()判断是否包含 判断指定字符或字符串是否包含在一个字符串内,返回值为true或者fals ...

  8. python字符串以什么标志结束_python字符串结束符

    python字符串结束符的更多内容_CSDN博客 2016-05-22 python 字符串末尾换行符处理 - qiqiaiairen的博客 - CSDN博... 找到以"imooc"开头和结尾的字符 ...

  9. python字符串是有序的吗_Python内置数据结构--字符串

    一.字符串 定义: 1.一个字符组成的有序的序列,是字符的集合,示例:'abcd' 2.使用单引号.双引号.三引号引住的内容字符序列 3.字符串是字面常量,一旦定义,不可修改,且有序.可迭代 初始化: ...

最新文章

  1. executeQuery,executeUpdate,execute区别
  2. Android开源框架——图片加载与缓存库 Picasso
  3. IT项目管理总结:第一章 项目管理概述
  4. ffplay命令汇总
  5. .net core ——微服务内通信Thrift和Http客户端响应比较
  6. 工作250:uniapp--实战--flex布局--星级评分
  7. 阿里大数据云原生化实践,EMR Spark on ACK 产品介绍
  8. fiddler修改支付金额_不容忽视的记账工具:支付宝记账
  9. 将整张网页存成png图片
  10. 案例:对比使用Java代码与EL表达式获取信息
  11. python 启动参数_python启动参数
  12. 02C++namespace命名空间
  13. python表格模板_python 网站 使用表单和模板
  14. Mac 苹果OS X小技巧:如何更改文件的默认打开方式
  15. 4款开源的中文分词系统
  16. 阅读《原则》有感之工作原则
  17. python判断邮箱格式是否正确_如何判断用户输入的邮箱格式是否正确?
  18. IPS需意识到高级闪避技术(AET)的危害
  19. input文本框--去首尾空格
  20. MT41K256M16TW-107 AUT:P美光内存颗粒D9TRN

热门文章

  1. C语言(CED)查找最接近的元素(分治法/二分查找):在一个非降序列中,查找与给定值最接近的元素。(递归实现)
  2. mysql 有外键 怎么插入数据_外键约束的表怎么插入数据
  3. Oracle GoldenGate微服务架构
  4. MySQL为什么要set names
  5. Linux下的一些简单网络配置命令介绍
  6. Angular 单元测试讲解
  7. Angular的@Output与@Input理解
  8. c#输出最大值、最小值和平均值(A)【C#】
  9. 逐行粒度的vuex源码分析
  10. 窄带物联网(NB-IoT)初步了解