python變量的引用以及在底層存儲原理

        Python的變量,粗放來說有數值型,布爾型,字符串類型,列表,元組,字典等6大類。那麼不同變量類型在底層是如何存儲的,關係到變量的引用,能否正確的掌握變量的相關操作?

#下面v1,v2的值分別是多少?爲什麼?
v1 =3
v2=v1
print("v2:",v2)
v1 += 2
print("v1:",v1)
print("v2:",v2)

#下面l2的值又是多少?爲什麼?
l1 = [1,2,3]
l2 =l1
print(l2)
l1.append(4)
print(l2)

1.變量的引用的底層原理

v1 =3
v2=v1            
print("v2:",v2)
v1 += 2          
print("v1:",v1)  
print("v2:",v2)   #v1的值變化了,爲什麼v2的值沒有跟着變化呢?
'''
執行結果如下:
v1: 5
v2: 3
'''
==================================
l1 = [1,2,3]
l2 =l1
print(l2)
l1.append(4)
print(l2)    #l1的值變化了,但是爲什麼l2的值也跟着變化了。
'''
執行結果如下:
[1, 2, 3]
[1, 2, 3, 4]
'''

要點分析:
  1.主要是因爲在Python中,對象分爲兩種:可變對象和不可變對象:不可變對象包括int,float,long,str,tuple等。可變對象包括list,dict等。
  2.需要注意的是:這裏說的不可變指的是值的不可變.對於不可變類型的變量,如果要更改變量,則會創建一個新值,把變量綁定到新值上,而舊值如果沒有被引用就等待垃圾回收。舉例如下:

  • 不可變類型:變量賦值 a=5 後再賦值 a=10,這裏實際是新生成一個 int 值對象 10,再讓 a 指向它,而 5 被丟棄,不是改變a的值,相當於新生成了a。

  • 可變類型:變量賦值 la=[1,2,3,4] 後再賦值 la[2]=5 則是將 list la 的第三個元素值更改,本身la沒有動,只是其內部的一部分值被修改了。

  3.本質是因爲不可變對象一旦新建後,系統就會根據他的大小給他分配固定死的內存,所以不允許修改,只修改值只能申請新的內存和地址。而可變對象,他的內存大小可以隨着值的變化而自動擴容     

代碼分析演示:

因爲變量在內存中新建時,系統都會給他分配一個地址,然後通過地址去查找或引用他的值。  Python的所有變量其實都是指向內存中的對象的一個指針,都是值的引用

代碼演示1:
v1 =3
v2=v1
print("v1在內存的地址:%d,v2在內存中地址:%d"%(id(v1),id(v2)))
v1 += 2
print("v1在內存的地址:%d,v2在內存中地址:%d"%(id(v1),id(v2)))
print("v1:",v1)
print("v2:",v2)
========================================================
v1在內存的地址:1747378992,v2在內存中地址:1747378992
v1在內存的地址:1747379024,v2在內存中地址:1747378992
v1: 5
v2: 3
'''
因爲:v1,v2都是int,爲不可變對象,所以一旦修改他們的值,包扣加減乘除賦值等操作,系統會在內存中給他們重新創建一個。
然後再把這個變量綁定(通過地址引用)到這個值上,所以v1 +=2後,他在內存中的地址變了。而v2依舊引用的是之前的地址,所以v2的值
沒有更新。

'''
代碼演示2:
l1 = [1,2,3]
l2 =l1
print("l1在內存的地址:%d,l2在內存中地址:%d"%(id(l1),id(l2)))
print(l2)
print("l1在內存的地址:%d,l2在內存中地址:%d"%(id(l1),id(l2)))
l1.append(4)
print(l2)
=======================================================
l1在內存的地址:34339096,l2在內存中地址:34339096
[1, 2, 3]
l1在內存的地址:34339096,l2在內存中地址:34339096
[1, 2, 3, 4]

對於可變對象如列表,l1,l2,當修改他們的值時,系統會自動給他們分配內存,所以不用修改地址。
=======================================================

代碼演示3:同理字符串等不可變的變量引用效果也一樣。
str1 ='hahhahah'
str2 = str1
str1 += "123"
print(str1,str2)
=======================================================
hahhahah123 hahhahah

3.變量的分類

可變類型與不可變類型

可變類型,值可以改變:

  • 列表 list
  • 字典 dict

不可變類型,值不可以改變:

  • 數值類型 int, long, bool, float
  • 字符串 str
  • 元組 tuple
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章