python里is和==的区别 python is和==的区别_缓存


在Python中对象之间比较是否相等可以用==,也可以用 is。因此也容易造成一些理解上的模糊,那两者是否有所区别呢?

在介绍is 与 == 的区别之前,首先要了解一下Python中对象的三个基本要素:

  • Id:身份标识,内存地址,用来唯一标识一个对象
  • Type:数据类型
  • Value:值

is 比较的是两个对象的 Id 是否相同,也就是比较两个对象是否为同一个实例对象,是否指向同一个内存地址is 为同一性运算符。

== 比较的是两个对象的Value 是否相等,默认会调用对象的eq()方法,==为比较操作符。

因此,我们也可以得出:如果两个对象相同(Id相同),则必然也相等(值相等),但如果两个对象相等,并不一定相同。所以在实际应用时,要有所区分,避免混用导致出现逻辑Bug。


通过例子,进一步理解 is 与 == 的区别


python里is和==的区别 python is和==的区别_缓存_02


执行上述代码,我们可以看到如下打印信息,正如上面所说,同一性运算符is 比较的是两个对象的Id是否相同,比较操作符 == 比较的是两个对象的值是否相等


python里is和==的区别 python is和==的区别_字符串_03


有没有一些情况下 is 和 == 结果完全相同?

数字类型


python里is和==的区别 python is和==的区别_python中//和/的区别_04


执行上述例子中的代码,我们来看一下输出信息,如下:


python里is和==的区别 python is和==的区别_缓存_05


为什么256时,is 与 == 的比较结果相同, 而1089时却不同?

因为,Python解释器为了提高整数类型使用的效率和使用性能,其内部做了很多的优化工作,对于整数对象,Python把一部分频繁使用的整数对象缓存起来,保存到小整数对象池缓存(small_ints)的链表中(Python2 为 [-5, 256] ,Python3 未知),任何需要引用这些整数对象的地方,都不再重新创建新的对象,而是直接引用缓存中的对象。


字符串类型


python里is和==的区别 python is和==的区别_缓存_06


执行上述例子中的代码,我们来看一下输出信息,如下:


python里is和==的区别 python is和==的区别_python里is和==的区别_07


为什么同样都是 'abc' 时,is 与 == 的比较结果相同, 而'adcadcadcadcadcadcadc'时却不同?

因为,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化,例如:Python解释器中使用了 intern(字符串驻留)的技术来提高字符串效率,即值同样的字符串对象仅仅会保存一份,放在一个字符串储蓄池中,需要注意的是,仅包括下划线、数字、字母的字符串才会被intern,同时不能超过20个字符。因为如果超过20个字符的话,解释器认为这个字符串不常用,不用放入字符串池中。


因此,当变量是数字、字符串、元组,列表,字典时,is 和 == 都不相同, 不能互换使用。当比较对象的值时,需使用 ==,比较对象Id(内存地址)时,需要使用is。


python里is和==的区别 python is和==的区别_python中//和/的区别_08