在
Python開發(fā)
中,比較兩個(gè)對(duì)象(變量)是否相等,可以用 “is”
和
“==”
操作,但它倆有什么區(qū)別?什么時(shí)候用
“is”
,什么時(shí)候用
“==”
?在面試時(shí),發(fā)現(xiàn)不少候選人很難把這兩者完全說清楚,因此在這篇文章中,將對(duì)二者進(jìn)行深入淺出的對(duì)比介紹。
先舉個(gè)例子
小黃最近手頭非常寬裕,花重金購買了一輛 P90D
特斯拉,我們暫且給這車取名叫
"
小
P"
,這輛車和隔壁老王家的車(車名叫
"
小 王
"
)是一模一樣的,無論是型號(hào)、外表還是價(jià)格都一樣,是同批次生產(chǎn)的。這里我們可以說
"
小
P"
和
"
小王
"
是兩輛一模一樣的、相等的(
euqal )
,但本質(zhì)上這是兩個(gè)不同的對(duì)象。有一天小君給他的愛車又取了一個(gè)網(wǎng)名叫
"
愛駒
"
,當(dāng)我們說
"
小
P"
的時(shí)候其實(shí)就是在討論
"
愛駒
"
,因?yàn)楸举|(zhì)上兩個(gè)名字指的是同一個(gè)對(duì)象,這里我們把
"
小
P"
和
"
愛駒
"
稱為完全相等的(
identical )
。
在 Python
中,
”==”
和
“is”
的區(qū)別可類比這個(gè)例子 ,前者是相等性比較,比較的是兩個(gè)對(duì)象中的值是否相等,后者是一致性比較,比較的是兩個(gè)對(duì)象的內(nèi)存空間地址是否相同。
顯然,如果內(nèi)存地址相同,那么他們的值肯定也是一樣的,因此,如果 “is”
返回
True
,那么
“==”
一定也返回
True
,反之卻不成立。
talk is cheap, show me the code
先創(chuàng)建一個(gè)列表對(duì)象,然后給它指定一個(gè)名字 a
,再定義另外一個(gè)變量
b
,讓它指向同一個(gè)對(duì)象。
>>> a = [1, 2, 3]
>>> b = a
a
和
b
打印的值都是相等的,因?yàn)檫@兩個(gè)變量指向的是同一個(gè)對(duì)象,就好比給一輛車起了兩個(gè)不同的名字。
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
理所當(dāng)然, is
和
==
都返回
True
。
>>> a == b
True
>>> a
is b
True
創(chuàng)建一個(gè)新的對(duì)象,盡管值是一樣的,但是他們本質(zhì)上是兩個(gè)不同的對(duì)象,處在兩個(gè)不同的內(nèi)存空間,因此 "is"
返回的是
False
。
>>> c = [1,2,3]>>> a is c
False
有且當(dāng)僅比較的兩個(gè)變量指向同一個(gè)對(duì)象時(shí) "is"
才返回
True
,而
"=="
最終取決于對(duì)象的
__eq__()
方法,本質(zhì)上兩個(gè)變量進(jìn)行
"=="
比較操作調(diào)用的是對(duì)象的
__eq__()
方法。例如:
>>>
class
Foo(object):
def
__eq__(self, other):
return
True
>>> f = Foo()
>>> f == 1
True
>>> f ==
None
True
>>> f
is
None
False
因?yàn)樽远x類 Foo
的
eq
方法恒返回
True
,因此它與任何對(duì)象進(jìn)行
"=="
都是返回
True
。而它與
None
是兩個(gè)不同的對(duì)象,因此
'is'
操作返回的是
False
。
最后請(qǐng)大家思考這段代碼,為什么同樣的操作會(huì)有不同的結(jié)果
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 123
>>> b = 123
>>> a is b
True
來源:FooFish
的筆錄