1. 程式人生 > >淺談python中的“ ==” 與“ is”

淺談python中的“ ==” 與“ is”

在python中,== 與 is 之間既有區別,又有聯絡,本文將通過實際程式碼的演示,力爭能夠幫助讀到這篇文章的朋友以最短的時間理清二者的關係,並深刻理解它們在記憶體中的實現機制。 扯淡的話不多說,下面馬上呈上我的第一張圖:

                                                                            通過上面程式碼的比較,我想很容易看得出," is" 是用來比較 a 和 b 是不是指向同一個記憶體單元,而"=="是用來比較 a 和 b指向的記憶體單元中的值是不是相等。下面敲黑板,如果你自己的實驗結果和我的不一致,請不要懷疑我,也不要懷疑自己的編譯器,我想你應該遇到了下面的這種情況:

上面這張圖和第一張圖沒有什麼區別,只是a 和 b的值由之前的500變成了3,但是結果卻和第一張大不相同,我們發現is和==在此時都為true並且a和b的地址完全相同。尼瑪,活見鬼了,我們之前的理解是a對應的500和b對應的500應該不在一個記憶體單元呀!其實這是python直譯器搞得鬼,具體是因為python的垃圾回收機制,這個垃圾回收機制會在之後的文章中詳細介紹,至於出現上面這種現象是因為一個叫小整數物件池的東西,python為了優化速度,會把【-5,256】之間的資料提前存放在小整數物件池中,程式中只要用的【-5,256】之間的資料不會再重新建立一份,都是指向物件池中的同一份資料,除了這個區間之外的資料,每次使用時系統都會重新申請一塊記憶體,用來儲存資料,這樣之前的現象也就不奇怪了。 到這裡,“ is ”和 “==”之間的恩怨情仇似乎介紹的差不多了,我們接下來再來單獨看看“==”。你是否想過python直譯器在底層是如何處理“==”的,或者說如何判斷兩個物件是否相等的呢? 對於數值型別的資料,只要兩個資料大小相等,那麼就是相等,但是對於非數值型的資料,比如字串,類建立的物件又是比較什麼呢?答案是python預設去比較兩個物件的地址,有圖有真相:

                                                        我們發現上圖中,p1和p2兩個物件的內容完全相同,但是python編譯器卻認為其不相等,這個時候就需要我們自己去定義規則去規定在什麼條件下兩個物件是相等的,具體操作需要去重寫python中的__eq__方法,通常把這個過程叫做運算子過載。下面這張圖就是完成運算子過載之後的操作,我們發現這時候兩個物件的值是相等的。  

對於“==”和 “is”的介紹到此就結束了,希望能幫到之前對此有過困惑的小夥伴,我先撤了哈。