歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python中的字符串駐留

Python中的字符串駐留

日期:2017/3/1 9:32:05   编辑:Linux編程

C#中的字符串駐留
熟悉.NET的人都應該知道C#中的字符串駐留機制,.NET維護了一個駐留池,它會把在編譯期間就相同的字符串只保留一份拷貝。如果僅在運行期間值才相同的字符串變量,.NET不會為這個2個相同的字符串變量指向同一份引用的。不過.NET提供了一個方法,讓開發人員可以強制將兩個相同的字符串指向同一個引用,使用String類中的Intern方法。

string s1 = "!QAZ2wsx3$%5$$%fe _ ###4@";
string s2 = "!QAZ2wsx3$%5$$%fe _ ###4@";
Console.WriteLine("s1,s2是否引用同一對象:" + object.ReferenceEquals(s1, s2));
string s3 = "bbbbb";
string s4 = string.Concat("bbb", "bbb");
Console.WriteLine("s3,s4是否引用同一對象:" + object.ReferenceEquals(s3, s4));
Console.WriteLine("調用Intern後..." );
s3 = String.Intern(s4);
Console.WriteLine("s3,s4是否引用同一對象:" + object.ReferenceEquals(s3, s4));

如下演示代碼:

這樣設計的合理性是因為string類型在C#中是屬於immutable的,即對string的修改,並不是在原來的內存塊上修改,而是重新開辟一塊新的空間,創建新的對象。
Python的String同樣也有駐留
Python中,同樣為immutable的String類型,也采用了這種字符串駐留機制。但Python中稍微有點小規則。
1,長度為0和1的字符串,默認都采用了駐留機制。
>>> a=''
>>> b=''
>>> a is b
True
>>> a='a'
>>> b='b'
>>> a is b
False
>>> a='!'
>>> b='!'
>>> a is b

2.編譯期間就確定了的字符串,也采用駐留機制,但是,僅限於以下這些字符:
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
先解釋一下什麼叫做編譯期間,Python是解釋型語言,但是事實上,它的解釋器也可以是理解為是一種編譯器,它負責將Python代碼翻譯成字節碼,也就是.pyc文件,之後再由Python虛擬機運行。這一點,和.Net的Framework、Java虛擬機很類似。(更多相關內容可以參考《Learning Python》),因此有些代碼會在翻譯成字節碼的時候,就自動的幫程序員預先計算了。

我們可以通過dis方法(分解Python中的字節碼 )來驗證,可以通過python -m dis xxx.py這樣的命令來查看
舉例:如下的一個Python文件test.py

a='abcdef'
b='abc'+'def'
c=''.join(['abc','def'])
print (a,b,c)
print ('a and b are same?',a is b)
print ('a and c are same?',a is c)

運行:

可以看到,變量a和b是同一個引用,但是a和c就不是了。再看其字節碼,可以看出,a和b在賦值的時候,就是相同的字符串,但是c就不同了,它是幾個字符串的拼裝,它是在運行期間才知道結果。
注意,必須是字符串必須是在"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"中,不然就不支持字符串駐留。
比如:
>>> a='abcdef!'
>>> b='abcdef!'
>>> a is b
False

3.通過乘法運算符得到的字符串,長度必須小於20。不然也無駐留機制
>>> a='abc'*6 #長度18
>>> b='abc'*6 #長度18
>>> a,b
('abcabcabcabcabcabc', 'abcabcabcabcabcabc')
>>> a is b
True
>>> a='abc'*7 #長度21
>>> b='abc'*7 #長度21
>>> a is b
False
這樣的設計目的是為了保護.pcy文件不會被錯誤代碼搞的過大,例如有人寫了‘abc’*10**10這種代碼。上述代碼也可以通過dis方式看到不同處。

4.和C#的字符串一樣,Pyhton也提供intern方法強制2個字符串指向同一個對象,如下代碼:
>>> import sys
>>> a='abcdef!'
>>> b='abcdef!'
>>> a is b
False
>>> a=sys.intern(b)
>>> a is b
True

5.實際上,對於整數數字,Python也會有駐留機制,但是只限於[-5,256]之間的數字。

--------------------------------------分割線 --------------------------------------

CentOS上源碼安裝Python3.4 http://www.linuxidc.com/Linux/2015-01/111870.htm

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

Python 語言的發展簡史 http://www.linuxidc.com/Linux/2014-09/107206.htm

Python 的詳細介紹:請點這裡
Python 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved