作為乙個例項,讓我們建立四個變數並為其賦值:
variable1 = 1
variable2 = "abc"
variable3 = (1,2)
variable4 = ['a',1]
#列印他們的ids
print('variable1: ', id(variable1))
print('variable2: ', id(variable2))
print('variable3: ', id(variable3))
print('variable4: ', id(variable4))
列印結果如下所示:
變數1:1747938368
變數2:152386423976
變數3:152382712136
loizaeasc變數4:152382633160
每個變數都被分配了乙個新的記憶體位址(以整數形式表示)。第乙個假設是,每當我們使用「 =」給變數賦值時,python都會建立乙個新的記憶體位址來儲存變數。這是100%正確的嗎?當然不是!
我將建立兩個新變數(5和6)並使用現有變數的值給它們賦值。
variable5 = variable1
variable6 = variable4
print('variable1: ', id(variable1))
print('variable4: ', id(variable4))
print('variable5: ', id(variable5))
print('variable6: ', id(variable6))
python列印結果:
變數1:1747938368
變數4:819035469000
變數5:1747938368
變數6:819035469000
你注意到,python並未為這兩個變數建立新的記憶體位址嗎?這次,它只是把兩個新變數都指向了現有變數相同的儲存位置。
現在讓我們為變數1設定乙個新值。注意:整數是不可變資料型別。
print('variable1: ', id(variable1))
variable1 = 2
print('variable1: ', id(variable1))
這將列印:
variable1: 1747938368
variable1: 1747938400
這意味著每當我們使用=並將新值給現有變數賦值時,就會在內部建立乙個新的記憶體位址來儲存該變數。讓我們看看它是否成立!
當值是可變資料型別時會發生什麼?variable6是乙個列表,讓我們在列表結尾append乙個值並列印其記憶體位址:
print('variable6:',id(variable6))
variable6.append('new')
print('variable6:',id(variable6))
請注意,變數的記憶體位址保持不變,因為它是可變資料型別,我們僅更新了其元素。
variable6:678181106888
variable6:678181106888
讓我們建立乙個函式並將乙個變數傳遞給它。如果我們在函式內部設定變數的值,它會發生什麼?讓我們評估一下。
def update_variable(variable_to_update):
print(id(variable_to_update))
update_variable(variable6)
print('variable6: ', id(variable6))
請注意,variable_to_update的id指向變數6的id。
這意味著如果我們在函式中更新variable_to_update且variable_to_update是可變資料型別,那麼variable6的值將更新。我們看乙個具體例子:
variable6 = ['new']
print('variable6: ', variable6)
def update_variable(variable_to_update):
variable_to_update.append('inside')
update_variable(variable6)
print('variable6: ', variable6)
這將列印:
variable6:['new']
variable6:['new','inside']
它向我們展示了如何在函式中的更新乙個可變的變數,你可以看到函式類和函式外的可變變數都具有相同的id。
如果我們在函式內給變數賦乙個新值(而不是更新),無論它是不可變的還是可變的資料型別,那麼一旦退出函式,更改將丟失:
print('variable6: ', variable6)
def update_variable(variable_to_update):
print(id(variable_to_update))
variable_to_update = ['inside']
update_variable(variable6)
print('variable6: ', variable6)
variable6:['new']
344115201992
variable6:['new']
現在是乙個有趣的場景:python並不總是為所有新變數建立乙個新的記憶體位址。
最後,如果我們為兩個不同的變數分配乙個字串值,例如「 a」,該怎麼辦它會建立兩個記憶體位址嗎?
variable_nine ="a"
variable_ten ="a"
print('variable9:',id(variable_nine))
print('variable10:',id(variable_ten))
注意,這兩個變數具有相同的記憶體位置:
variable9:792473698064
variable10:792473698064
如果我們建立兩個不同的變數並為其分配乙個長字串值,該怎麼辦:
variable_nine = "a" * 21
variable_ten = "a" * 21
print('程式設計客棧variable9: ', id(variable_nine))
print('variable10: ', id(variable_ten))
這次python為兩個變數建立了兩個不同記憶體位置:
variable9:541949933872
variable10:541949933944
為什麼? 這是因為python啟動時會建立乙個內部值快取,這樣做是為了提供更快的結果。python會為少量整數(如-5到256之間)和較小的字串值分配了少量的記憶體位址。這就是我們示例中的短字串都具有相同id的原因,而長字串的id則不同。
有時我們想檢查兩個物件是否相等。
var1 = "a"&nbsloizaeascp;* 30
var2 = "a" * 30
print('var1:',id(var1))#318966315648
print('var2:',id(var2))#168966317364
print('==:', var1 www.cppcns.com== var2)#返回true
print('is:',var1 is var2)#返回false
python記憶體分配機制
python中數值型別是不可變物件,當程式試圖改變資料的值時,程式會重新生成新的資料,而不是改變原來的資料。python函式的引數都是物件的引用,如果在引用不可變物件時嘗試修改物件,程式會在函式中生成新的物件 開闢新的位址空間 函式外被引用的物件則不會被改變。num 1 defadd num num...
C C 記憶體分配機制
1.c語言中的記憶體機制 在c語言中,記憶體主要分為如下5個儲存區 1 棧 stack 位於函式內的區域性變數 包括函式實參 由編譯器負責分配釋放,函式結束,棧變數失效。2 堆 heap 由程式設計師用malloc calloc realloc分配,free釋放。如果程式設計師忘記free了,則會造...
memcached記憶體分配機制
memcached slab allocator分配機制 slab allocator的基本原理是按照預先規定的大小,將分配的記憶體分割成特定長度的塊,以完全解決記憶體碎片問題。slab allocation的原理相當簡單,就是將分配的記憶體分割成各種尺寸的塊 chunk 並把尺寸相同的塊分成組 c...