Python中的字符串駐留

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#

clipboard

這樣設計的合理性是由於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)

運行:

clipboard[1]

能夠看到,變量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方式看到不一樣處。

clipboard[2]

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/

相關文章
相關標籤/搜索