詳解python的變量緩存機制
變量的緩存機制
變量的緩存機制(以下內容僅對python3.6.x版本負責)
機制
隻要有兩個值相同,就隻開辟一個空間
為什麼要有這樣的機制
在計算機的硬件當中,內存是最重要的配置之一,直接關系到程序的運行速度和流暢度。在過去計算機內存資源昂貴而小的年代中,程序的內存管理成為編程中的重要技術之一。python沒有C/C++中的指針那樣的定義可以編程者自主的控制內存的分配,而是有一套自動的內存地址分配和緩存機制。在這個機制當中,可以把一些相同值的變量在內存中指向同一塊區域,而不再重新開辟一個空間,這樣就達到瞭節省內存的目的。
python中使用id()函數查看數據的內存地址
number部分
整型
對於整型而言,-5~~正無窮的范圍內的相同值的id地址一致
# 在後續的版本中所有的數的id地址都一致 # 相同 print(id(9999999), id(9999999)) print(id(100), id(100)) print(id(-5), id(-5)) # 不同 print(id(-6), id(-6))
浮點型
對於浮點型而言,非負數范圍內的相同值id一致
# 相同 print(id(9999999.0), id(9999999.0)) print(id(100.0), id(100.0)) # 不同 print(id(-5.0), id(-5.0)) print(id(-6.0), id(-6.0))
佈爾值
對於佈爾值而言,值相同測情況下,id一致
# 相同 print(id(True), id(True)) print(id(False), id(False))
復數
復數在(實數+虛數)這樣的結構當中永不相同,隻有單個虛數相同才會一致
# 相同 print(id(1j), id(1j)) print(id(0j), id(0j)) # 不同 print(id(1234j), id(3456j)) print(id(1+1j), id(1+1j)) print(id(2+0j), id(2+0j))
容器部分
字符串
字符串在相同的情況下,地址相同
# 相同 print(id('hello '), id("hello ")) # 不同 print(id('msr'), id('wxd'))
字符串配合使*號使用有特殊的情況:
乘數為1:隻要數據相同,地址就是相同的
# 等於1,和正常的情況下是一樣的,隻要值相同地址就是一樣的 a = 'hello ' * 1 b = 'hello ' * 1 print(a is b) a = '祖國' * 1 b = '祖國' * 1 print(a is b)
乘數大於1:隻有僅包含數字、字母、下劃線時地址是相同的,而且字符串的長度不能大於20
# 純數字字母下劃線,且長度不大於20 a = '_70th' * 3 b = '_70th' * 3 c = '_70th_70th_70th' print(a, id(a), len(a)) print(b, id(b), len(b)) print(c, id(c), len(c)) print(a is b is c) ''' 結果: _70th_70th_70th 1734096389168 15 _70th_70th_70th 1734096389168 15 _70th_70th_70th 1734096389168 15 True '''
# 純數字字母下劃線,長度大於20 a = 'motherland_70th' * 3 b = 'motherland_70th' * 3 c = 'motherland_70thmotherland_70thmotherland_70th' print(a, id(a), len(a)) print(b, id(b), len(b)) print(c, id(c), len(c)) print(a is b is c) ''' 結果: motherland_70thmotherland_70thmotherland_70th 2281801354864 45 motherland_70thmotherland_70thmotherland_70th 2281801354960 45 motherland_70thmotherland_70thmotherland_70th 2281801354768 45 False '''
# 有其它字符,且長度不大於20 a = '你好' * 3 b = '你好' * 3 c = '你好你好你好' print(a, id(a), len(a)) print(b, id(b), len(b)) print(c, id(c), len(c)) print(a is b is c) ''' 結果: 你好你好你好 3115902573360 6 你好你好你好 3115902573448 6 你好你好你好 3115900671904 6 False '''
字符串指定駐留
使用sys模塊中的intern函數,讓變量指向同一個地址,隻要字符串的值是相同的,無論字符的類型、長度、變量的數量,都指向同一個內存地址。
語法:intern(string)
from sys import intern a = intern('祖國70華誕: my 70th birthday of the motherland' * 1000) b = intern('祖國70華誕: my 70th birthday of the motherland' * 1000) c = intern('祖國70華誕: my 70th birthday of the motherland' * 1000) d = intern('祖國70華誕: my 70th birthday of the motherland' * 1000) e = intern('祖國70華誕: my 70th birthday of the motherland' * 1000) print(a is b is c is d is e)
元組
元組隻有為空的情況下,地址相同
# 相同 print(id(()), id(tuple())) # 不同 print(id((1, 2)), id((1, 2)))
列表、集合、字典
任何情況下,地址都不會相同
# 列表、非空元組、集合、字典 無論在聲明情況下,id表示都不會相同 # 不同 print(id([]), id([])) print(id(set()), id(set())) print(id({}), id({}))
總結
# -->Number 部分 1.對於整型而言,-5~正無窮范圍內的相同值 id一致 2.對於浮點數而言,非負數范圍內的相同值 id一致 3.佈爾值而言,值相同情況下,id一致 4.復數在 實數+虛數 這樣的結構中永不相同(隻有虛數的情況例外,隻有虛數的虛數相同才會id一致) # -->容器類型部分 5.字符串 和 空元組 相同的情況下,地址相同 6.列表,元組,字典,集合無論什麼情況 id標識都不同 [空元組例外]
小數據池
以下內容僅對python3.6.8負責
數據在同一個文件(模塊)當中,變量存儲的的緩存機制就是上述的那樣。
但是如果是在不同文件(模塊)當中的數據,部分數據就會駐留在小數據池當中。
什麼是小數據池
不同的python文件(模塊)中的相同數據的本應該是不在同一個內存地址當中的, 而是應該全新的開辟一個新空間,但是這樣就造成瞭內存的空間壓力,所以python定義瞭小數據池的概念,默認允許小部分數據即使在不同的文件當中,隻要數據相同就可以使用同一個內存空間,節省內存。
小數據池支持什麼類型
小數據池隻針對:int、bool、None關鍵字 ,這些數據類型有效。
int
對於int而言,python在內存中創建瞭-5 ~ 256 范圍的整數,提前駐留在瞭內存的一塊區域,如果是不同文件(模塊)的兩個變量,聲明同一個值,在-5~256這個范圍裡,那麼id一致,兩個變量的值都同時指向一個值的地址,節省空間。
# 現在我們打開兩個終端,進入python環境中,然後執行下面的指令,你會發現,隻有-5 ~ 256范圍內的整型的id值相同,而不是之前說過的是-5 ~ 正無窮的范圍,這是因為,兩個終端環境就相當於兩個python文件或者是模塊。 print(id(1000)) print(id(500)) print(id(257)) print(id(256)) print(id(-5)) print(id(-6))
其它
佈爾、None這些類型都是有效的
# 開啟兩個終端測試吧 print(id(True)) print(id(False)) print(id(None))
到此這篇關於python的變量緩存機制的文章就介紹到這瞭,更多相關python的變量緩存機制內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!