在
Python开发
中,比较两个对象(变量)是否相等,可以用 “is”
和
“==”
操作,但它俩有什么区别?什么时候用
“is”
,什么时候用
“==”
?在面试时,发现不少候选人很难把这两者完全说清楚,因此在这篇文章中,将对二者进行深入浅出的对比介绍。
先举个例子
小黄最近手头非常宽裕,花重金购买了一辆 P90D
特斯拉,我们暂且给这车取名叫
"
小
P"
,这辆车和隔壁老王家的车(车名叫
"
小 王
"
)是一模一样的,无论是型号、外表还是价格都一样,是同批次生产的。这里我们可以说
"
小
P"
和
"
小王
"
是两辆一模一样的、相等的(
euqal )
,但本质上这是两个不同的对象。有一天小君给他的爱车又取了一个网名叫
"
爱驹
"
,当我们说
"
小
P"
的时候其实就是在讨论
"
爱驹
"
,因为本质上两个名字指的是同一个对象,这里我们把
"
小
P"
和
"
爱驹
"
称为完全相等的(
identical )
。
在 Python
中,
”==”
和
“is”
的区别可类比这个例子 ,前者是相等性比较,比较的是两个对象中的值是否相等,后者是一致性比较,比较的是两个对象的内存空间地址是否相同。
显然,如果内存地址相同,那么他们的值肯定也是一样的,因此,如果 “is”
返回
True
,那么
“==”
一定也返回
True
,反之却不成立。
talk is cheap, show me the code
先创建一个列表对象,然后给它指定一个名字 a
,再定义另外一个变量
b
,让它指向同一个对象。
>>> a = [1, 2, 3]
>>> b = a
a
和
b
打印的值都是相等的,因为这两个变量指向的是同一个对象,就好比给一辆车起了两个不同的名字。
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
理所当然, is
和
==
都返回
True
。
>>> a == b
True
>>> a
is b
True
创建一个新的对象,尽管值是一样的,但是他们本质上是两个不同的对象,处在两个不同的内存空间,因此 "is"
返回的是
False
。
>>> c = [1,2,3]>>> a is c
False
有且当仅比较的两个变量指向同一个对象时 "is"
才返回
True
,而
"=="
最终取决于对象的
__eq__()
方法,本质上两个变量进行
"=="
比较操作调用的是对象的
__eq__()
方法。例如:
>>>
class
Foo(object):
def
__eq__(self, other):
return
True
>>> f = Foo()
>>> f == 1
True
>>> f ==
None
True
>>> f
is
None
False
因为自定义类 Foo
的
eq
方法恒返回
True
,因此它与任何对象进行
"=="
都是返回
True
。而它与
None
是两个不同的对象,因此
'is'
操作返回的是
False
。
最后请大家思考这段代码,为什么同样的操作会有不同的结果
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 123
>>> b = 123
>>> a is b
True
来源:FooFish
的笔录