Python中的“特權種族”是什麼?
Value的比較符號用雙等號“==”,上例中比較l1和l2的Value要寫成“l1 == l2”,明顯兩者的Value是相等的。按照約定俗成的習慣,我們把Value值相等的兩個物件稱為“相等”,而把Id值相等的兩個物件稱為“相同”。
所以,準確地說,上例的l1與l2相等,但是他們不相同,l1==l2,但l1 is not l2。
特權種族:共用記憶體的物件
每個物件被創建出來的時候,就會確定其Id標識,也就是給它分配記憶體地址。通常來說,新物件的記憶體地址也是新的,會從未分配的可用地址中取。
但是,為了提高記憶體利用效率,對於一些常用的物件,如一些數值較小的數字物件、布林值物件、None物件、較短的字串物件等等,python採取共用物件記憶體的分配策略。
# 新分配記憶體地址的例子 ww=[1,2] ee=[1,2] id(ww)==id(ee) >>>False a=2018 b=2018 id(a)==id(b) >>>False # 共用記憶體地址的例子 a=100 b=100 id(a)==id(b) >>>True f1=True f2=True id(f1)==id(f2) >>>True n1=None n2=None id(n1)==id(n2) >>>True s="python_cat" t="python_cat" id(s)==id(t) >>>True
這就意味著,python中出現了“特權種族”,執行環境早早就為它們分配好了記憶體地址,一旦要建立新的物件時,先去特權種族中查詢,有Type和Value相等的物件,則新物件不分配新的記憶體空間,而是指向已有物件。
“特權種族”的存在,使得我們不需要頻繁建立這些物件,既能提高已分配記憶體的使用率,又減少了建立物件、分配新記憶體的損耗。
對於共用記憶體地址的數字物件的取值範圍,根據這篇文章《Python中神祕的-5到256》(連結見文末)對python原始碼的分析,文中有如下結論:
Python中,對於整數物件,如果其值處於[-5,256]的閉區間內,則值相同的物件是同一個物件。
對於共用記憶體地址的字串物件的取值範圍,學習了幾篇對python原始碼分析的文章後(連結見文末),貓貓總結出大致有以下結論:
Python中,字串使用Intern機制實現記憶體地址共用,長度不超過20,且僅包括下劃線、數字、字母的字串才會被intern;涉及字串拼接時,編譯期優化結果會與執行期計算結果不同。
# 編譯對字串拼接的影響 s1 = "hell" s2 = "hello" "hell" + "o" is s2 >>>True s1 + "o" is s2 >>>False # "hell" + "o"在編譯時變成了"hello", # 而s1+"o"因為s1是一個變數,在執行時才拼接,所以沒有被intern