前言
Python 中对象的比较有两种方式 == 和 is。两种方式都能判断操作符两侧的变量值是否相等,那么它们的区别是什么呢?通过下面的介绍我们来一探究竟。
比较操作符通常用于条件语句,如下示例:
if a == b: pass
if a is False: pass
== 与 is 的区别
== 操作符比较对象的值是否相等。小明有一块 劳力士 手表,小李也有一块同款 劳力士 手表,这时我们就认为这两块手表相等。
小明的手表 = 劳力士
小李的手表 = 劳力士
小明的手表 == 小李的手表
is 操作符比较对象的身份标识是否相等,即对象在内存中的地址是否相同,如果两个对象的身份标识相等,就说明它们是同一个对象。小明的爸爸称呼小明叫 儿子,小明的女朋友称呼小明叫 老公,但这两个称呼都代表 小明 这个人,即为同一个对象。
爸爸的儿子 = 小明
女朋友的老公 = 小明
爸爸的儿子 is 女朋友的老公
接下来就用代码来展示一下 == 与 is 的区别:
> a = [1, 2, 3] > b = [1, 2, 3] > a == b True > a is b False > id(a) 24603664 > id(b) 24603144
> a = [1, 2, 3] > b = a > a == b True > a is b True > id(a) 24604144 > id(b) 24604144
在 Python 中 id 函数接收一个对象作为参数,并返回该对象在内存中的地址。
由以上代码可以分析出:== 操作符只比较两个对象的值是否相等,但不比较两个对象是否为同一个对象;而 is 操作符并不是比较两个对象的值是否相等,而是会确认两个对象是否为同一个对象,如果为同一个对象,那么它们的值自然相等。
Python 小整数对象池
以上两段代码已经能够体现出 == 与 is 的区别,不过 Python 中也有一些特殊情况,来看下面例子:
> a = 5 > b = 5 > a == b True > a is b True > id(a) 1730274128 > id(b) 1730274128
> a = 257 > b = 257 > a == b True > a is b False > id(a) 48558688 > id(b) 48558720
以上代码看起来就很怪异了,同样的比较操作,只是换了一个数字结果就不同了。
其实出现以上结果的原因在于 Python 自身。Python 出于性能上的考虑,在解释器启动的时候就已经将 -5 到 256 的整数创建到内存中了。而当我们需要创建值在 -5 到 256 的 int 数字的时候,Python 并不会新开辟一块内存去创建数字,而是直接将已存在的对象返回。
但是如果新创建的数字不在这个范围,Python 就会为每个变量单独开辟自己的内存空间。
Python intern 机制
再来看下面关于字符串比较的例子:
> a = 'hello world' > b = 'hello world' > a == b True > a is b False > id(a) 49465408 > id(b) 49465448
> a = 'hello' > b = 'hello' > a == b True > a is b True > id(a) 49429152 > id(b) 49429152
想必根据之前数字比较的例子,你大概也能猜测到以上代码结果不同的原因了。事实上,以上结果同样是 Python 出于对性能的考虑,不过这次 Python 并没有预先将 hello 字符串创建到内存中,而是使用了一种叫 intern 的机制。
关于 intern 机制在这里我们不去深究,以后有机会专门写一篇博客来介绍。总之你需要知道在某些场景下,Python 会对字符串开启 intern 机制来提高性能,从而导致出现上面示例代码的结果。
== 与 is 各自的适用场景
什么时候用 ==、什么时候用 is 呢?
当我们需要比较一个变量与一个 单例 的时候,应该使用 is,其他情况通常使用 ==。
例如拿一个变量去跟 True 或 False 进行比较的时候就应该使用 is,因为用 is 的比较的速度要比用 == 更快。
用 is 比较对象的时候,只需要判断它们是否处于同一块内存地址即可,而用 == 比较更慢的原因在于当用 == 去比较对象的时候会调用对象的 __eq__() 方法,而 __eq__() 方法通常会被重载,执行其内部逻辑往往会多花一些时间。
以下就是一个重载对象 __eq__() 方法的例子:
class MyList(object): def __init__(self, *args): self._list = [*args] def __eq__(self, other): result = False for i in self._list: for j in other._list: if i == j: break else: break else: result = True return result li_1 = MyList(1, 2, 3) li_2 = MyList(1, 2, 3) print(li_1 == li_2) # True
你可以自行尝试修改 __eq__() 方法内部的逻辑来观察其结果。
总结
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]