当前位置: 首页 > 后端技术 > Python

Python中对象的比较操作==和is

时间:2023-03-26 14:45:05 Python

Python中比较对象有两种方式==和is。这两种方法都可以判断运算符两边的变量值是否相等,那么它们有什么区别呢?让我们通过下面的介绍一探究竟。比较运算符通常用在条件语句中,如下例:ifa==b:passifaisFalse:pass==和is的区别==运算符比较对象的值是否相等。小明有一块劳力士表,小李也有一块同款的劳力士表。这时候,我们就认为这两款手表是平等的。小明的手表=劳力士小李的手表=劳力士小明的手表==小李的手表is运算符比较对象的标识是否相等,即对象在内存中的地址是否相同。如果两个对象的标识相等,则表示它们是同一个对象。小明的爸爸叫小明“儿子”,小明的女朋友叫小明“老公”,但这两个名字代表的是小明,也就是同一个对象。爸爸的儿子=小明女朋友的老公=小明爸爸的儿子是女朋友的老公接下来用代码来说明==和is的区别:>>>a=[1,2,3]>>>b=[1,2,3]>>>a==bTrue>>>aisbFalse>>>id(a)24603664>>>id(b)24603144>>>a=[1,2,3]>>>b=a>>>a==bTrue>>>aisbTrue>>>id(a)24604144>>>id(b)24604144在Python中,id函数将一个对象作为参数并返回内存中地址中的对象。从上面的代码可以看出,==运算符只比较两个对象的值是否相等,而不会比较两个对象是否是同一个对象;而is运算符并不比较两个对象的值是否相等,而是会确认这两个对象是否是同一个对象,如果是同一个对象,那么它们的值自然是相等的。Python小整数对象池上面两段代码已经可以体现==和is的区别,但是Python中有一些特殊情况,看下面的例子:>>>a=5>>>b=5>>>a==bTrue>>>a是bTrue>>>id(a)1730274128>>>id(b)1730274128>>>a=257>>>b=257>>>a==bTrue>>>a是bFalse>>id(a)48558688>>>id(b)48558720上面的代码看起来很奇怪,同样的比较操作,只是换了一个数,结果不一样。其实造成以上结果的原因在于Python本身。出于性能原因,Python已经在解释器启动时将-5到256之间的整数创建到内存中。而当我们需要创建一个-5到256之间的int型数字时,Python不会开辟新的内存来创建数字,而是直接返回已有的对象。但是如果新创建的数字不在这个范围内,Python会为每个变量分别开辟自己的内存空间。Pythonintern机制我们来看下面这个字符串比较的例子:>>>a='helloworld'>>>b='helloworld'>>>a==bTrue>>>aisbFalse>>>id(a)49465408>>>id(b)49465448>>>a='你好'>>>b='你好'>>>a==bTrue>>>aisbTrue>>>id(a)49429152>>>id(b)49429152想必根据前面的数值对比例子,你大概可以猜到上面代码结果不同的原因了。其实上面的结果也是出于Python的性能考虑,只不过这次Python并没有预先将hello字符串创建到内存中,而是使用了一种叫做intern的机制。intern机制这里就不深究了,以后有机会专门写博客介绍一下。总之,你需要知道,在某些场景下,Python会为字符串开启intern机制来提升性能,从而导致上面示例代码的结果。==和is的适用场景什么时候用==什么时候用is?当我们需要比较一个变量和一个单例时,我们应该使用is,否则我们通常使用==。例如,在比较一个变量与True或False时,应该使用is,因为用is比较的速度比==快。using是比较对象时,只需要判断是否在同一内存地址即可,而使用==比较慢的原因是当使用==比较对象时,对象的__eq__()方法会被调用,并且__eq__()方法通常被重载,执行其内部逻辑通常需要更长的时间。下面是一个重载对象__eq__()方法的例子:self._list:forjinother._list:ifi==j:breakelse:breakelse:result=Truereturnresultli_1=MyList(1,2,3)li_2=MyList(1,2,3)print(li_1==li_2)#True你可以尝试修改__eq__()方法内部的逻辑来观察结果。