Python中对象的比较操作==和is区别详析

 更新时间:2021年02月12日 11:20:56   作者:江湖十年  
这篇文章主要给大家介绍了关于Python中对象的比较操作==和is区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

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__() 方法内部的逻辑来观察其结果。

总结

到此这篇关于Python中对象的比较操作==和is的文章就介绍到这了,更多相关Python对象比较操作==和is内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python jieba库用法及实例解析

    Python jieba库用法及实例解析

    这篇文章主要介绍了Python jieba库用法及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Python类的定义、继承及类对象使用方法简明教程

    Python类的定义、继承及类对象使用方法简明教程

    这篇文章主要介绍了Python类的定义、继承及类对象使用方法简明教程,本文用浅显易懂的语言讲解了类的定义、继承及类对象的使用,非常实用易懂,需要的朋友可以参考下
    2015-05-05
  • Transpose 数组行列转置的限制方式

    Transpose 数组行列转置的限制方式

    今天小编就为大家分享一篇Transpose 数组行列转置的限制方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • python tornado协程调度原理示例解析

    python tornado协程调度原理示例解析

    这篇文章主要为大家介绍了python tornado协程调度原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • python学习之面向对象【入门初级篇】

    python学习之面向对象【入门初级篇】

    Python从第一天开始就是面向对象的语言。正因为如此,创建和使用类和对象是非常地容易。这篇文章主要介绍了python中面向对象的相关资料,属于python面向对象学习的初级篇,本章将帮助您在使用Python面向对象编程的技术方面所有提高,有需要的朋友可以参考借鉴。
    2017-01-01
  • Python全栈之作用域和闭包

    Python全栈之作用域和闭包

    这篇文章主要为大家介绍了Python作用域和闭包,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • Python实现排序算法、查找算法和图遍历算法实例

    Python实现排序算法、查找算法和图遍历算法实例

    这篇文章主要介绍了Python实现排序算法、查找算法和图遍历算法实例,排序算法、查找算法和图遍历算法是计算机科学中常见且重要的算法。它们在数据处理、搜索和图结构等领域发挥着关键作用,需要的朋友可以参考下
    2023-08-08
  • python 使用pdfminer3k 读取PDF文档的例子

    python 使用pdfminer3k 读取PDF文档的例子

    今天小编就为大家分享一篇python 使用pdfminer3k 读取PDF文档的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Django自带的加密算法及加密模块详解

    Django自带的加密算法及加密模块详解

    今天小编就为大家分享一篇Django自带的加密算法及加密模块详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Flask与SMTP协议邮件扩展问题

    Flask与SMTP协议邮件扩展问题

    这篇文章主要介绍了Flask与SMTP协议邮件扩展问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12

最新评论