在Python中會用到對象之間比較,可以用==,也可以用is。但是它們的區別是什么呢?
is比較的是兩個實例對象是不是完全相同,它們是不是同一個對象,占用的內存地址是否相同。萊布尼茨說過:“世界上沒有兩片完全相同的葉子”,這個is正是這樣的比較,比較是不是同一片葉子(即比較的id是否相同,這id類似于人的身份證標識)。
==比較的是兩個對象的內容是否相等,即內存地址可以不一樣,內容一樣就可以了。這里比較的并非是同一片葉子,可能葉子的種類或者脈絡相同就可以了。默認會調用對象的__eq__()方法。
可以通過如下例子來區分比較下:
>>>a=["I","love","Python"]
>>>b=a
#a的引用復制給b,在內存中其實是指向了用一個對象
>>>bisa
True
>>>id(a)
46381384
>>>id(b)
46381384
#當然,內容也肯定是相等的
>>>b==a
True
可以發現b和a的內存地址是相同的,它們指向同一塊內存,因而is和==的結果都為True。這是因為直接賦值都是賦值的引用,是引用,是引用,重要的事情說三遍。但如果不是通過引用賦值,而是通過切片賦值呢?
#b通過切片操作重新分配了對象,但是值和a相同
>>>b=a[:]
>>>bisa
False
>>>id(a)
48740680
>>>id(b)
48740680
>>>b==a#但他們的值還是相等的
True
新建對象之后,b和a指向了不同的內存,所以bisa的結果為False,而b==a的結果為True。在這里,小編提一個問題,b[0]isa[0]的結果呢?
答案是True。因為切片拷貝是淺拷貝,列表中的元素并未重新創建。不理解的同學請翻看之前的文章Python中的淺拷貝與深拷貝。
通常,我們關注的是值,而不是內存地址,因此Python代碼中==出現的頻率比is高。但是什么時候用is呢?
is與==相比有一個比較大的優勢,就是計算速度快,因為它不能重載,不用進行特殊的函數調用,少了函數調用的開銷而直接比較兩個整數id。而a==b則是等同于a.__eq__(b)。繼承自object的__eq__方法比較兩個對象的id,結果與is一樣。但是多數Python的對象會覆蓋object的__eq__方法,而定義內容的相關比較,所以比較的是對象屬性的值。
在變量和單例值之間比較時,應該使用is。目前,最常使用is的地方是判斷對象是不是None。下面是推薦的寫法:
aisNone
判斷不是None的推薦寫法是:
aisnotNone
Python會對比較小的整數對象進行緩存,下次用的時候直接從緩存中獲取,所以is和==的結果可能相同:
>>>a=1
>>>b=1
>>>aisb
True
>>>a==b
True
而看一下另外一段代碼:
>>>a=257
>>>b=257
>>>aisb
False
這是什么原因呢?
注意,Python僅僅對比較小的整數對象進行緩存(范圍為范圍[-5,256])緩存起來,而并非是所有整數對象。需要注意的是,這僅僅是在命令行中執行,而在Pycharm或者保存為文件執行,結果是不一樣的,這是因為解釋器做了一部分優化。
總結
1、is比較兩個對象的id值是否相等,是否指向同一個內存地址;
2、==比較的是兩個對象的內容是否相等,值是否相等;
3、小整數對象[-5,256]在全局解釋器范圍內被放入緩存供重復使用;
4、is運算符比==效率高,在變量和None進行比較時,應該使用is。
以上內容為大家介紹了Python中的比較:is與==,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。