is 和 == 的區別
相信學過 Python 小伙伴們都知道 is 和 == 都是用來比較 Python 物件的,但是區別就是
- is 比較需要物件的值和記憶體地址都相等
-
== 比較只需要物件的值相等就行了
我們來看一個例子


我們可以看到,time 模塊的 time() 方法用于獲取當前時間,所以 t1 和 t2 的值都是一樣的
== 用來判斷 t1 和 t2 的值是否相等,所以回傳 True
雖然 t1 和 t2 的值相等,但它們是兩個不同的物件(每次呼叫 time() 都回傳不同的物件),所以t1 is t2回傳 False
那么,如何判斷兩個物件是否相同呢?
答:判斷兩個物件的記憶體地址,如果記憶體地址相同,說明兩個物件使用的是同一塊記憶體,當然就是同一個物件了
我們來看下 t1 和 t2 的記憶體地址


可以看到它們兩個的記憶體地址是不一樣的

小整數池&快取機制
但是有小伙伴可能會遇到下面的這種情況

咦?怎么 a is b 結果是 True?這應該是兩個不同的物件啊
這其實是因為小整數池
python 中經常使用的一些數值定義為小整數池,小整數池的范圍是[-5,256]
python 對這些數值已經提前創建好了記憶體空間,即使多次重新定義也不會再重新開辟新的空間,但是小整數池外的數值在重新定義時都會再次開辟新的空間
所以對于小整數池中的數,記憶體地址一定是相同的,小整數池中外的數,記憶體地址是不同的

好,那這次我用小整數池之外的數



?玩我是吧,說好的小整數池中外的數,記憶體地址是不同的,那上面的代碼結果怎么跟說的不一樣
上面的代碼我是在 IDE 環境下面敲的,我們試著在互動模式下敲


可以看到,在互動模式下,小整數池外的數記憶體地址不相同,這是為什么呢?
先說結論:這是因為 Python 的快取機制,所以在 IDE 環境或者腳本模式下同一個整數被多個變數參考不會開辟新的記憶體空間

Python 快取機制
-
Python 解釋器啟動時會先從記憶體空間中開辟出來一小部分,用于存盤高頻使用的資料(不可變資料型別),這樣可以大大減少高頻使用的資料物件創建時申請記憶體和銷毀時撤銷記憶體的開銷
-
在同一代碼塊下,不可變資料型別的物件(數字,字串,元祖)被多個變數參考,不會重復開辟記憶體空間
由上面得知,只有不可變的資料型別(字串、元祖、基礎資料型別)如果被多個變數參考,是不會重復開辟記憶體空間,但可變資料型別(串列、字典、集合)就除外
-
可變資料型別
我們來看看



在互動模式下結果也是如此

-
不可變資料型別
1、小整數池里的數
我們來看下互動模式下的不可變資料型別的快取機制

可以看到,Python 中整數范圍 [-5, 256] 中的數為固定快取,只要是使用到該范圍內的數字,不管是直接賦值還是運算式計算得到的,都會使用固定快取中的資料
2、非小整數池里的數
對于非小整數池里的數,在 IDE 環境下會使用到快取,即多個變數參考同一個資料,不會開辟新的記憶體空間

對于非小整數池里的數,在互動模式下,除非同時賦值或者在同一個局域代碼塊里面賦值,否則不會使用快取機制


intern 機制
我們知道,由于 Python 的快取機制:
-
不可變的資料型別(字串、元祖、基礎資料型別)如果被多個變數參考,是不會重復開辟記憶體空間
-
但可變資料型別(串列、字典、集合)被多個變數參考就會開辟新的記憶體空間
-
對于小整數池里的整數,被多個變數參考,不會重復開辟記憶體空間
但是到目前為止我們知道:在互動模式下,除了特殊情況(同時賦值、同一局域代碼塊內賦值)以及小整數池之外,所有資料在被多個變數參考時都會開辟新的記憶體空間
其實還有一種特殊情況,我們來看這么一個例子

看著輸出的結果,再跟剛剛所學到的知識做一下對比,是不是發現有不對勁的地方
互動模式下,多個變數參考字串(不可變資料型別)應該是開辟新的記憶體空間啊,為啥上面的例子沒有開辟
intern機制
字串型別作為Python中最常用的資料型別之一,Python 為了提高字串使用的效率和使用性能,使用了 intern(字串駐留)的技術來提高字串效率
即值同樣的字串物件僅僅會保存一份,放在一個字串儲蓄池中,是共用的,有新的變數參考同樣的字串的時候,不會開辟新的記憶體空間,而是參考這個共用的字串
-
原理
實作 Intern 機制的方式非常簡單,就是通過維護一個字串儲蓄池,這個池子是一個字典結構,如果字串已經存在于池子中就不再去創建新的字串,直接回傳之前創建好的字串物件,如果之前還沒有加入到該池子中,則先構造一個字串物件,并把這個物件加入到池子中去,方便下一次獲取
下面是偽代碼

1、在互動模式下,只包含字母數字下劃線的字串才會觸發 intern 機制


2、在 IDE 環境或者腳本模式下,只要長度不超過20(長度限制),即使使用特殊字符也會觸發 intern 機制


PS:我在寫這篇文章的時候用的是 python 3.9,發現沒有長度限制了,都會觸發 intern 機制

感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548572.html
標籤:Python
