C#中的字符串駐留python
熟悉.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));
以下演示代碼:c#
這樣設計的合理性是由於string類型在C#中是屬於immutable的,即對string的修改,並非在原來的內存塊上修改,而是從新開闢一塊新的空間,建立新的對象。ide
Python的String一樣也有駐留post
Python中,一樣爲immutable的String類型,也採用了這種字符串駐留機制。但Python中稍微有點小規則。ui
1,長度爲0和1的字符串,默認都採用了駐留機制。spa
>>> 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]之間的數字。
參考文檔
http://guilload.com/python-string-interning/
http://www.laurentluce.com/posts/python-string-objects-implementation/