Python中对象的比较操作==和is区别详析
前言
Python中对象的比较有两种方式==和is。两种方式都能判断操作符两侧的变量值是否相等,那么它们的区别是什么呢?通过下面的介绍我们来一探究竟。
比较操作符通常用于条件语句,如下示例:
ifa==b: pass
ifaisFalse: pass
==与is的区别
==操作符比较对象的值是否相等。小明有一块劳力士手表,小李也有一块同款劳力士手表,这时我们就认为这两块手表相等。
小明的手表=劳力士
小李的手表=劳力士
小明的手表==小李的手表
is操作符比较对象的身份标识是否相等,即对象在内存中的地址是否相同,如果两个对象的身份标识相等,就说明它们是同一个对象。小明的爸爸称呼小明叫儿子,小明的女朋友称呼小明叫老公,但这两个称呼都代表小明这个人,即为同一个对象。
爸爸的儿子=小明
女朋友的老公=小明
爸爸的儿子is女朋友的老公
接下来就用代码来展示一下==与is的区别:
>>>a=[1,2,3] >>>b=[1,2,3] >>>a==b True >>>aisb False >>>id(a) 24603664 >>>id(b) 24603144
>>>a=[1,2,3] >>>b=a >>>a==b True >>>aisb True >>>id(a) 24604144 >>>id(b) 24604144
在Python中id函数接收一个对象作为参数,并返回该对象在内存中的地址。
由以上代码可以分析出:==操作符只比较两个对象的值是否相等,但不比较两个对象是否为同一个对象;而is操作符并不是比较两个对象的值是否相等,而是会确认两个对象是否为同一个对象,如果为同一个对象,那么它们的值自然相等。
Python小整数对象池
以上两段代码已经能够体现出==与is的区别,不过Python中也有一些特殊情况,来看下面例子:
>>>a=5 >>>b=5 >>>a==b True >>>aisb True >>>id(a) 1730274128 >>>id(b) 1730274128
>>>a=257 >>>b=257 >>>a==b True >>>aisb False >>>id(a) 48558688 >>>id(b) 48558720
以上代码看起来就很怪异了,同样的比较操作,只是换了一个数字结果就不同了。
其实出现以上结果的原因在于Python自身。Python出于性能上的考虑,在解释器启动的时候就已经将-5到256的整数创建到内存中了。而当我们需要创建值在-5到256的int数字的时候,Python并不会新开辟一块内存去创建数字,而是直接将已存在的对象返回。
但是如果新创建的数字不在这个范围,Python就会为每个变量单独开辟自己的内存空间。
Pythonintern机制
再来看下面关于字符串比较的例子:
>>>a='helloworld' >>>b='helloworld' >>>a==b True >>>aisb False >>>id(a) 49465408 >>>id(b) 49465448
>>>a='hello' >>>b='hello' >>>a==b True >>>aisb 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__()方法的例子:
classMyList(object): def__init__(self,*args): self._list=[*args] def__eq__(self,other): result=False foriinself._list: forjinother._list: ifi==j: break else: break else: result=True returnresult li_1=MyList(1,2,3) li_2=MyList(1,2,3) print(li_1==li_2)#True
你可以自行尝试修改__eq__()方法内部的逻辑来观察其结果。
总结
到此这篇关于Python中对象的比较操作==和is的文章就介绍到这了,更多相关Python对象比较操作==和is内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!