在 Python 中,比較兩個物件(變數)是否相等,可以用 “is” 和 “==” 操作,但它倆有什麼區別?什麼時候用 “is”,什麼時候用 “==” ?在面試時,發現不少候選人很難把這兩者完全說清楚,因此在這篇文章中,「Python之禪」將對二者進行深入淺出的對比介紹。
先舉個例子
小黃最近手頭非常寬裕,花重金購買了一輛 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.net/what-is-dif…
公眾號:Python之禪 (id:VTtalk),分享 Python 等技術乾貨