1. 程式人生 > >你不知道的Python(1)

你不知道的Python(1)

這將會一個系列的文章,相當於是在觀看Github上的一個有趣專案wtfpython之後一個隨筆。

字串的駐留[string interning]

我們首先看一個示例:

會發現,用兩種不同方式定義的相同內容的字串,他們的id是相同的

那麼我們再看一個例子:

會發現,具有相同內容的不同變數,他們實際上是指向同一個記憶體地址。那麼照此類推,我們可以猜測,即使兩個字串變數的定義方式或者變數名不同,但是實際上他們是指向同一個記憶體地址。

但是事實果真如此嗎?請看第三個示例:

此時變數a、b內容完全一樣,但是(a is b)得到的結果卻是false。

那麼接下來的兩個示例也會讓你同樣摸不著頭腦:

為什麼會出現這種情況呢?其實這都是由一個被稱作字串駐留的行為導致的:Cpython 在編譯優化時, 某些情況下會嘗試使用已經存在的不可變物件而不是每次都建立一個新物件。發生駐留之後, 許多變數可能指向記憶體中的相同字串物件. (從而節省記憶體)

而剛才我們所看到的程式碼都是字串發生的隱式駐留。那麼什麼情況下會發生隱式駐留呢:

1、所有長度為0和1的字串都會自動駐留;

2、字串在被編譯時駐留 ('str' 將被駐留, 但是 ''.join(['s', 't', 'r'] 將不會被駐留);

3、字串中只包含字母,數字或下劃線時將會駐留(所以上面程式碼中的"string!"由於含有!而不會發生駐留,所以最後結果為false);

4、當在同一行將 a 和 b 的值設定為 "string!" 的時候, Python 直譯器會建立一個新物件, 然後同時引用第二個變數. 如果你在不同的行上進行賦值操作, 它就不會“知道”已經有一個 string 物件;

5、常量摺疊(constant folding) 是 Python 中的一種 窺孔優化(peephole optimization) 技術. 這意味著在編譯時表示式 'a'*20會被替換為 'aaaaaaaaaaaaaaaaaaaa' 以減少執行時的時鐘週期. 只有長度小於 20 的字串才會發生常量摺疊。

為什麼會有這種限制呢?你可以想象一下當後面跟的數字極大的時候,比如為10**1000,那麼其帶來的代價將是極大的

好了,這就是在這裡要跟大家分享的關於python的一個小特性。

大家可以去多多支援原作者,原連結如下:https://github.com/leisurelicht/wtfpython-cn#structure-of-the-examples%E7%A4%BA%E4%BE%8B%E7%BB%93%E6%9E%84