比如1,2,3這些int
類型的數據,幾乎每一次使用for
循環都會用到它們。即:
在python
裡提供了對象池技術。int
類型數據是不可變對象,這意味著它可以被共享,在python
啟動之後,就會在內存中申請一片內存,將頻繁使用的小整數存儲在這裡,在整個程序運行期間,這些小整數都一直存在,不會被銷毀,對它們的使用,僅僅增加了它們的引用計數而已。
那麼有多少整數被緩存了呢?這個范圍其實不大,只有[-5, 257]
。當然如果你想擴大這個范圍,你可以選擇修改python
源碼來解決。
在python
交互式解釋器裡來驗證:
>>> a = 12
>>> b = 12
>>> id(a)
140705565998496
>>> id(b)
140705565998496
>>> a = 257
>>> b = 257
>>> id(a)
2389141537712
>>> id(b)
2389141537904
觀察上面的結果,可以發現在緩存范圍內,其內存地址不變,反之,則變。
對於字符串同樣也是如此。假設有100個變量,都賦值為python
,難道真得要在內存當中創建100個對象?為此,python
提供了intern
機制。簡單來說,python
內部維護一個字典(interned
),當一個字符串需要駐留時,就去interned
中查看這個字符串是否已經存在,如果存在則增加引用計數,不存在的話就增加到字典中。
使用駐留技術,有下面兩個好處:
什麼時候發生駐留
在
python
交互式解釋器裡來驗證會准確些
編譯時發生駐留,運行時不駐留
s1 = 'py' + 'thon'
print(s1 is 'python')
a = 'py'
b = 'thon'
print(a+b is 'python')
# 輸出結果
# True
# False
結果差異原因:s1
值是在編譯階段就計算出來的,因此會駐留,而a+b
只有在運行階段才會計算,因此沒有發生駐留
只含大小寫字母、數字、下劃線時發生駐留
s1 = 'python'
s2 = 'python'
print(s1 is s2)
a1 = 'pyth on'
b2 = 'pyth on'
print(a1 is b2)
# 輸出結果
# True
# False
字符串長度為0或1
空字符串和長度為1的字符串默認都會駐留,python
認為這樣的字符串都是經常被使用的字符串
被sys.intern
指定駐留
from sys import intern
s1 = intern('python!')
s2 = intern('python!')
print(s1 is s2)
用乘法(*)
得到的字符串
這部分是比較復雜的規則 ,先來看乘數是1的情況:
字符串只包含下劃線,數字,字母,默認駐留
字符串長度小於等於1,默認駐留
>>> s1 = "hello"
>>> s2 = s1*1
>>> s1 is s2
True
如果乘數大於2,規則如下:
字符串只包含下劃線,數字,字母且長度小於等於20,默認駐留
含有其它字符時,不論長度是多少,都不駐留
>>> s1 = "pythonpythonpython"
>>> s2 = "python"*3
>>> s1 is s2
True
>>> s1 = "&&&"
>>> s2 = "&" * 3
>>> s1 is s2
False
1.錯誤描述運行環境:windows10、pycharm、p
List of articles python Crawl