關(guān)于python變量的引用以及在底層存儲原理
Python的變量,簡單來說有數(shù)值型,布爾型,字符串類型,列表,元組,字典等6大類。那么不同變量類型在底層是如何存儲的,關(guān)系到變量的引用,能否正確的掌握變量的相關(guān)操作
下面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的值沒有跟著變化呢? '''
執(zhí)行結(jié)果如下:
v1: 5
v2: 3
'''
l1 = [1,2,3] l2 =l1 print(l2) l1.append(4) print(l2) #l1的值變化了,但是為什么l2的值也跟著變化了。 '''
執(zhí)行結(jié)果如下:
[1, 2, 3]
[1, 2, 3, 4]'''
要點分析:
- 可變對象和不可變對象:不可變對象包括
int
,float
,string
,tuple
等??勺儗ο蟀╨ist,dict,自定義類的實例等。 - 在
python
中通過= 復(fù)制的變量,都是同時即把變量的值,也把變量在內(nèi)存中的地址復(fù)制也過去了。即=復(fù)制過的變量不僅內(nèi)存地址一樣,變量的值也一樣。但是需要注意的是:對于不可變類型(如int)的變量,如果要更改變量的值,則會創(chuàng)建一個新值,并且給這個新值分配一個新的內(nèi)存地址,然后把變量指向這個新值的內(nèi)存地址上,而舊值如果沒有被引用就等待垃圾回收。如果是可變類型變量。如果修改變量的值,則可以直接修改變量的值,變量的引用地址不會變。
不可變類型:變量賦值 a=5
后再賦值 a=10,這里實際是新生成一個 int 值對象 10,再讓 a 指向它,而 5 被丟棄,不是改變a的值,相當于新生成了a。
可變類型:變量賦值 la=[1,2,3,4]
后再賦值 la[2]=5 則是將 list la 的第三個元素值更改,本身la沒有動,只是其內(nèi)部的一部分值被修改了。
- 本質(zhì)是因為不可變對象一旦新建后,系統(tǒng)就會根據(jù)他的大小給他分配固定死的內(nèi)存,所以不允許修改,只修改值只能申請新的內(nèi)存和地址。而可變對象,他的內(nèi)存大小可以隨著值的變化而自動擴容
代碼分析演示:
因為變量在內(nèi)存中新建時,系統(tǒng)都會給他分配一個地址,然后通過地址去查找或引用他的值。 Python的所有變量其實都是指向內(nèi)存中的對象的一個指針,都是值的引用
代碼演示1:
v1 =3 v2=v1 print("v1在內(nèi)存的地址:%d,v2在內(nèi)存中地址:%d"%(id(v1),id(v2))) v1 += 2 print("v1在內(nèi)存的地址:%d,v2在內(nèi)存中地址:%d"%(id(v1),id(v2))) print("v1:",v1) print("v2:",v2) ======================================================== v1在內(nèi)存的地址:1747378992,v2在內(nèi)存中地址:1747378992 v1在內(nèi)存的地址:1747379024,v2在內(nèi)存中地址:1747378992 v1: 5 v2: 3 '''
因為:v1,v2都是int,為不可變對象,所以一旦修改他們的值,包扣加減乘除賦值等操作,系統(tǒng)會在內(nèi)存中給他們重新創(chuàng)建一個。
然后再把這個變量綁定(通過地址引用)到這個值上,所以v1 +=2后,他在內(nèi)存中的地址變了。而v2依舊引用的是之前的地址,所以v2的值
沒有更新。
'''
代碼演示2:
l1 = [1,2,3] l2 =l1 print("l1在內(nèi)存的地址:%d,l2在內(nèi)存中地址:%d"%(id(l1),id(l2))) print(l2) print("l1在內(nèi)存的地址:%d,l2在內(nèi)存中地址:%d"%(id(l1),id(l2))) l1.append(4) print(l2) print("l1在內(nèi)存的地址:%d"%(id(l1))) ======================================================= l1在內(nèi)存的地址:37345880,l2在內(nèi)存中地址:37345880 [1, 2, 3] l1在內(nèi)存的地址:37345880,l2在內(nèi)存中地址:37345880 [1, 2, 3, 4] l1在內(nèi)存的地址:37345880
對于可變對象如列表,l1,l2,當修改他們的值時,系統(tǒng)會自動在原地址上給他們擴容內(nèi)存,所以不用修改地址。
代碼演示3:同理字符串等不可變的變量引用效果也一樣。
str1 ='hahhahah' str2 = str1 str1 += "123" print(str1,str2) hahhahah123 hahhahah
2.變量的分類
可變類型與不可變類型
可變類型,值可以改變:
- 列表
list
- 字典
dict
不可變類型,值不可以改變:
- 數(shù)值類型
int
,long
,bool
,float
- 字符串
str
- 元組
tuple
到此這篇關(guān)于關(guān)于python變量的引用以及在底層存儲原理的文章就介紹到這了,更多相關(guān)python變量的引用以及在底層存儲原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中*args和**kwargs的區(qū)別詳解
這篇文章主要介紹了Python中*args和**kwargs的區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(四):域名系統(tǒng)
當我們在上網(wǎng)的時候,通常輸入的是網(wǎng)址,其實這就是一個域名,而我們計算機網(wǎng)絡(luò)上的計算機彼此之間只能用IP地址才能相互識別2014-06-06jupyter .ipynb轉(zhuǎn).py的實現(xiàn)操作
這篇文章主要介紹了jupyter .ipynb轉(zhuǎn).py的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03Python中的高級數(shù)據(jù)結(jié)構(gòu)詳解
這篇文章主要介紹了Python中的高級數(shù)據(jù)結(jié)構(gòu)詳解,本文講解了Collection、Array、Heapq、Bisect、Weakref、Copy以及Pprint這些數(shù)據(jù)結(jié)構(gòu)的用法,需要的朋友可以參考下2015-03-03在Python開發(fā)環(huán)境中調(diào)用ChatGPT模型詳細過程
在開發(fā)過程當中時常需要使用 ChatGPT 來完成一些任務(wù),但總是使用網(wǎng)頁交互模式去 Web 端訪問 ChatGPT 是很麻煩的,這時候我們可以使用代碼來調(diào)用 ChatGPT 模型,本文將詳細介紹在 Python 開發(fā)環(huán)境中調(diào)用 ChatGPT 模型過程,,需要的朋友可以參考下2023-05-05