Python中的變量賦值
引言:
Python
中的變量在使用中很流暢,可以不關(guān)注類型,任意賦值,對于開發(fā)來說效率得到了提升,但若不了解其中的機(jī)理,往往也會犯一些小錯,讓開發(fā)進(jìn)行的不那么流暢,本文就是從語言設(shè)計和底層原理的角度,帶大家理解Python中的變量。
下面我們從一個簡單例子開始:
a = 3
當(dāng)我們代碼中寫入a=3
時到底發(fā)生了啥,從概念上來說,Python
會執(zhí)行三個不同的步驟來完成這個請求:
- 創(chuàng)建了一個對象來代表值3
- 若是a尚未創(chuàng)建會創(chuàng)建一個變量a
- 將變量a和新的對象3進(jìn)行關(guān)聯(lián),稱變量a為對象3的一個引用
上文提到的三個關(guān)鍵字,“對象
”、“變量
”、“引用
”是Python
中讓變量得以運作的關(guān)鍵,我們在下一小節(jié)細(xì)細(xì)道來。
1 變量、對象、引用
先從概念說起:
對象是分配的一塊內(nèi)存,有足夠的空間去表示它們所代表的值。
變量是一個系統(tǒng)表的元素,擁有指向?qū)ο蟮倪B接的空間。
引用時自動形成的從變量到對象的指針。
接著上文中a=3的三個步驟,咱們增加一句代碼:
a = 3 b = a
下面通過一張圖表征了兩句話執(zhí)行的結(jié)果:
關(guān)于b=a
引發(fā)的操作為b同樣也指向了3,建立了從變量b到對象3的引用,此部分實現(xiàn)了python
的賦值操作。此部分引出了Python中的賦值操作的秘密,下面咱們先來看一下為什么Python中變量賦值時不用指定變量的類型呢,實際上從上面的概念中已經(jīng)發(fā)現(xiàn)了一個重要定義:
>>> 類型屬于對象,而不是變量
為了理解對象類型是如何使用的,我們看一下對一個變量多次賦值的結(jié)果:
a = 3 a = 'wali' a = 3.1415926
從表面上看,a開始是一個整數(shù),接著變成一個字符串,最后變成一個浮點,對于學(xué)習(xí)過C語言的人來說,這個是無法理解的,但對于python
來說,這是可以執(zhí)行的??雌饋硐袷莂的類型在連續(xù)改變,實際上我們理解了變量、引用、對象的概念以及“類型屬于對象,而不是變量”這些知識后,我們會發(fā)現(xiàn),實際發(fā)生了如下的事情:
執(zhí)行中分別創(chuàng)建了整數(shù)類型的對象3,字符串的對象“wali
”以及浮點數(shù)的對象3.14,變量a并不擁有這些類型,只是簡單的通過引用分別指向了三個對象。
進(jìn)一步深入研究就會發(fā)現(xiàn),從Python
語言實現(xiàn)的角度來說,每個對象都包含了一個頭部信息,其中就標(biāo)識了這個對象的類型。
此外,還有一個概念“引用計數(shù)器”,我們再來看下,最開始的代碼:
a = 3 b = a
可能聰明的讀者已經(jīng)心里默默計算出對于對象3的引用計數(shù)器的值為2,分別為變量a和變量b對對象3的引用。是的,引用計數(shù)器的定義就是這么明了,用于表征用于指向同一個對象的引用的個數(shù)。通過變量間的賦值操作,自動的計算對象的引用計數(shù)。
那么,我們又會問引用計數(shù)器有啥用呢,為啥要多此一舉來計算有多少個變量引用同一個變量呢,此時我們引出一個新的概念:對象的垃圾回收。
2 對象的垃圾回收機(jī)制
有一段代碼:
a = 3 a = 'wali' a = 3.1415926
我們會進(jìn)一步思考,當(dāng)我把a(bǔ)從指向整數(shù)對象3改變?yōu)橹赶蜃址畬ο蟆?code>wali'時,那對象3發(fā)生了啥 ?難道一直放在內(nèi)存里,如果對象非常大,那豈不是很占用內(nèi)存,實際上Python
設(shè)計者早就為我們考慮的很周全了:
在Python
中,每當(dāng)一個變量名被賦予了一個新的對象,之前的那個對象空間就會被回收(前提為此對象沒有被其他的變量名或?qū)ο笏茫?,這種自動回收對象空間的技術(shù)叫做垃圾回收。
這里如何判斷何時回收,就得用到上一節(jié)所說的一個非常重要的概念,對象引用計數(shù)器,當(dāng)計數(shù)器值為0標(biāo)識無變量或?qū)ο笠?,自動回收對象空間。到此,我們明白了對象引用計數(shù)器的重要作用,也理解了,除了我們看到的代碼,Python
也在默默的為我們做不少自動化的事情。
3 變量所指向的對象不同會有何不同?
#example 1 a = 3 b = a a = 5
我們回到上面的例子中,如果a發(fā)生變化,那么b會跟著發(fā)生變化嗎?理論上指向同一個對象是會跟著發(fā)生變化的,但是這里的答案是不會,因為對象3是數(shù)字,不可變對象,所以只能重新創(chuàng)建一個新的對象5,然后a指向?qū)ο?,但是如果a所指向的對象是一個可變的對象,比如說列表,就會和我們想的一樣b也會跟著發(fā)生變化,如下面的例子所示:
#example 2 a = [1,2,3] b = a a[0] = 3 L = a is b >>>True M = a == b >>>True
那么看下面的例子,例子2 和例子3 有什么區(qū)別呢?
#example 3 a = [1,2,3] b = [1,2,3] L = a is b >>>False M = a == b >>>True
在python
中有兩種方法檢測變量是否相等,is 和 == ,其中==是判斷變量所指向的對象的值是否相等,is是判斷對象的同一性,如果兩個變量精確的指向同一對象,is操作符才會返回True
,也可以理解為is
操作符,是比較實現(xiàn)引用的指針是否相同,例子2中變量a和變量b指向同一個對象,所以L和M都是True
,但是例子三中變量a和變量b指向不同的對象,所以才會出現(xiàn)例子3下面的L和M的值的不一樣的情況~但是如果下面的例子又會出現(xiàn)不同的結(jié)果:
#example 4 a = 3 b = 3 L = a is b >>>True M = a == b >>>True #example 5 c = [1,2,3] K = c[2] is a >>>True
是為什么呢?因為3 為不可變對象,為了節(jié)省內(nèi)存消耗,只會保留一份,不管有多少個引用指向?qū)ο?,對象3都只有一份,例子5也很好的證明了這一點~
例子4和例子5中變量和對象的引用關(guān)系
課外小知識:
(1)可變類型,值可以改變:主要包括list列表,dict
字典;不可變類型,值不可以改變:主要包括:數(shù)值類型int
、long
、bool
、float
,字符串str
,元組tuple
在例子3中變量a和b的所指向的對象為可變對象,并且a和b的地址不一樣,但是a和b中的元素所指向的對象其實是一樣的,如下圖所示
到此這篇關(guān)于Python中的變量賦值的文章就介紹到這了,更多相關(guān)Python變量賦值內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。