Python中的 is 和 == 以及字符串驻留机制详解


Posted in Python onJune 28, 2019

is 和 ==

先了解下官方文档中关于 is 和 == 的概念。is 表示的是对象标示符(object identity),而 == 表示的是相等(equality);is 的作用是用来检查对象的标示符是否一致,也就是比较两个对象在内存中的地址是否一样(相当于检查 id(a) == id(b)),而 == 是用来检查两个对象引用的值是否相等(相当于检查 a.eq(b));这点和Java有点类似,只不过Java中是用 == 来比较两个对象在内存中的地址,用 equals() 来检查两者之间的值是否相等。

is ==
概念 对象标示符 相等
作用 比较对象在内存中的地址 检查两个对象引用的值
示例 id(a) == id(b) a.eq(b)

字符串驻留机制

Python中的字符串采用了intern机制,当需要值相同的字符串的时候(比如标识符),可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接和修改字符串是会比较影响性能的。

因为是不可变的,所以字符串的操作都不是replace,而是新建对象,这也是为什么拼接多字符串的时候不建议用+而用join(),join()是先计算出所有字符串的长度,然后再拷贝,只new一次对象。

需要注意的是,并不是所有的字符串都会采用intern机制,当且仅当只包含下划线、数字、字母的字符串才会被intern。

相关示例

示例一

a = "hello"
b = "hello"
print(a is b) # 输出 True 
print(a == b) # 输出 True

值相同的简单字符串对象在字符串池里只会保存一份,这决定了字符串必须是不可变对象,所以a和b是同一个对象

示例二

a = "hello world"
b = "hello world"
print(a is b) # 输出 False
print(a == b) # 输出 True

a和b中都有空格,所以不会被intern(空格不是python标识符),故a和b不是同一个对象。注意,这仅仅是在交互式命令行中执行,而在PyCharm或者保存为文件执行,结果是不一样的,主要是因为解释器做了一部分优化

示例三

a = 'ab' + 'c' is 'abc'
print(a) # 输出 True
ab = 'ab'
b = ab + 'c' is 'abc'
print(b) # 输出 False

第一个'ab'+'c'是在compile-time(编译期)求值的,被替换成了'abc',所以输出为True;第二个示例,ab+'c'是在run-time(运行期)拼接的,导致没有被自动intern

示例四

a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # 输出 False
print(a == b) # 输出 True

a和b是列表,不是同一个对象

示例五

a = [1, 2, 3]
b = a
print(a is b) # 输出 True 
print(a == b) # 输出 True

把a的引用复制给b(引用赋值),在内存中其实是指向同一个对象

示例六

a = ["I", "love", "Python"]
b = a[:]
print(a is b) # 输出 False
print(a == b) # 输出 True
print(a[0] is b[0]) # 输出 True
print(a[0] == b[0]) # 输出 True

b通过切片操作重新分配了对象(切片赋值),但值和a相同。由于切片拷贝是浅拷贝,这说明列表中的元素并未重新创建,因此a[0] is b[0]输出为True

示例七

a = 1
b = 1
print(a is b) # 输出 True
print(a == b) # 输出 True

Python会对比较小的整数对象进行缓存,下次用的时候直接从缓存中获取

示例八

a = 320
b = 320
print(a is b) # 输出 False
print(a == b) # 输出 True

Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256]),而并非是所有整数对象。注意,这仅仅是在交互式命令行中执行,而在PyCharm或者保存为文件执行,结果是不一样的,主要是因为解释器做了一部分优化

is 与 == 对比

is 与 == 相比计算速度会更快,因为它不能重载,不用进行特殊的函数调用,通过直接比较两个整数 id,减少了函数调用的开销。而 a == b 则是等同于a.eq(b),继承自 object 的 eq 方法原本也是比较两个对象的id,结果与 is 一样,但大多数Python对象会覆盖重写object的 eq 方法,而定义内容的相关比较,所以比较的是对象属性的值。

在变量和单例值之间比较时,应该使用 is。目前,最常使用 is 的地方是当判断对象是不是 None,下面是推荐的写法: xxx is None;判断不是None的推荐写法是: xxx is not None

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
仅用50行代码实现一个Python编写的计算器的教程
Apr 17 Python
简单介绍Python的Tornado框架中的协程异步实现原理
Apr 23 Python
Python while 循环使用的简单实例
Jun 08 Python
python+selenium开发环境搭建图文教程
Aug 11 Python
利用python如何处理百万条数据(适用java新手)
Jun 06 Python
Python3.5面向对象编程图文与实例详解
Apr 24 Python
使用python进行波形及频谱绘制的方法
Jun 17 Python
Pandas之groupby( )用法笔记小结
Jul 23 Python
pytorch使用指定GPU训练的实例
Aug 19 Python
深入了解Python在HDA中的应用
Sep 05 Python
500行代码使用python写个微信小游戏飞机大战游戏
Oct 16 Python
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
Apr 14 Python
Python实现 PS 图像调整中的亮度调整
Jun 28 #Python
Python绘图Matplotlib之坐标轴及刻度总结
Jun 28 #Python
python启动应用程序和终止应用程序的方法
Jun 28 #Python
简单了解python高阶函数map/reduce
Jun 28 #Python
安装好Pycharm后如何配置Python解释器简易教程
Jun 28 #Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
Jun 28 #Python
python识别图像并提取文字的实现方法
Jun 28 #Python
You might like
Zend Studio (eclipse)使用速度优化方法
2011/03/23 PHP
改写ThinkPHP的U方法使其路由下分页正常
2014/07/02 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
PHP内存使用情况如何获取
2015/10/10 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
js判断页面中是否有指定控件的简单实例
2014/03/04 Javascript
HTML5之WebSocket入门3 -通信模型socket.io
2015/08/21 Javascript
不能不知道的10个angularjs英文学习网站
2016/03/23 Javascript
AngularJS基础 ng-init 指令简单示例
2016/08/02 Javascript
js实现文字截断功能
2016/09/14 Javascript
jsp 自动编译机制详细介绍
2016/12/01 Javascript
详解网站中图片日常使用以及优化手法
2017/01/09 Javascript
Vue中添加过渡效果的方法
2017/03/16 Javascript
React+react-dropzone+node.js实现图片上传的示例代码
2017/08/23 Javascript
深入理解vuex2.0 之 modules
2017/11/20 Javascript
解决低版本的浏览器不支持es6的import问题
2018/03/09 Javascript
vue构建动态表单的方法示例
2018/09/22 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
2019/01/23 Javascript
JS使用百度地图API自动获取地址和经纬度操作示例
2019/04/16 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
深入探究Python中变量的拷贝和作用域问题
2015/05/05 Python
Python实现把数字转换成中文
2015/06/29 Python
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
Python遍历文件夹和读写文件的实现方法
2017/05/10 Python
Python实现针对json中某个关键字段进行排序操作示例
2018/12/25 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
2019/07/22 Python
python生成任意频率正弦波方式
2020/02/25 Python
Python 实现将大图切片成小图,将小图组合成大图的例子
2020/03/14 Python
css3背景图片透明叠加属性cross-fade简介及用法实例
2013/01/08 HTML / CSS
德国运动营养和健身网上商店:Myprotein.de
2018/07/18 全球购物
师德师风个人总结
2015/02/06 职场文书
消防安全培训工作总结
2015/10/23 职场文书
私人贷款担保书该怎么写呢?
2019/07/02 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
i7 6700处理器相当于i5几代
2022/04/19 数码科技