Python字符串的intern機制和大小整數對象池

很少BB,直接上實例設計

字符串的Intern機制

(1)
>>> a = 'hello'
>>> b = 'hello'
>>> print(id(a),id(b))
2037326236784 2037326236784

>>> a = 'hello world'
>>> b = 'hello world'
>>> print(id(a),id(b))
2037326180976 2037326180784

(2)
>>> a = 'hello'*4
>>> b = 'hello'*4
>>> print(id(a), id(b))
2037326166320 2037326166320

>>> a = 'hello'*5
>>> b = 'hello'*5
>>> print(id(a), id(b))
2037326142960 2037326143040

(3)
>>> a = ' '    # 字符串中有一個空格
>>> b = ' '    # 字符串中有一個空格
>>> print(id(a), id(b))
2037324558664 2037324558664

有朋友可能碰到這些狀況時納悶,怎麼肥四?其實這是Python字符串的intern機制的鍋,該機制規定:當兩個或以上的字符串變量它們的值相同且僅由數字字母下劃線構成並且長度在20個字符之內,或者值僅含有一個字符時,內存空間中只建立一個對象來讓這些變量都指向該內存地址。當字符串不知足該條件時,相同值的字符串變量在建立時都會申請一個新的內存地址來保存值。code

小整數對象池

Python字符串有intern機制的限制,一樣的,整形數也有大小整數對象池的限制。Python語言在設計之初爲了減小頻繁申請和銷燬內存的資源開銷,規定了[-5, 256]之間的整數所有常駐在內存中且不會被垃圾回收只能增減引用計數,這就是小整數對象池,池外的數在建立時每次都得申請新的內存空間而不是增長引用計數。例子以下:對象

>>> a = 256
>>> b = 256
>>> print(id(a), id(b))
1953505712 1953505712
>>> a = 257
>>> b = 257
>>> print(id(a), id(b))
2037325924592 2037325924368

大整數對象池

在交互式終端環境中,每次建立大型數時都是去申請新的內存空間。可是在編寫Python文件時每次運行都把代碼加載到內存中,整個項目代碼都屬於一個總體。這時就是大型整數對象池發揮做用的時候了,它把處於相同代碼塊的全部等值的大型整數變量都處理爲一個對象。不懂就看實例。內存

class A(object):
    a = 100
    b = 100
    c = 1000
    d = 1000


class B(object):
    a = 100
    b = 1000


print(A.a is A.b)  # True
print(A.a is B.a)  # True
print(A.c is A.d)  # True  重點是這一個
print(A.b is B.b)  # False

瞅見了吧,類A和類B在同一文件中,雖然1000超出了[-5, 256]的範圍可是仍是把他們處理成同一個對象了。資源

題外擴展

擴展點Python內存管理方面的姿式吧,我也是剛看到的,順便貼這兒了,但願對大家有用。字符串

>>> id([1,2,3]) == id([4,5,6])
True
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> print(id(a), id(b))
2037326252488 2037326229256

有人問爲何id([1,2,3]) == id([4,5,6]),這是由於Python會實時銷燬沒有引用計數的對象。一旦在內存中建立了一個對象可是沒有爲其添加引用計數,該段代碼執行完後就會回收地址,在這個例子中計算完[1,2,3]的id後list被銷燬,計算右邊的id時list實時建立,複用了左邊list用過的內存。可是生成的時間有前後,他們並不表明同一個對象。內存管理

相關文章
相關標籤/搜索