對象vs變量
成都創(chuàng)新互聯(lián)是一家專注于網(wǎng)站設(shè)計、成都做網(wǎng)站與策劃設(shè)計,劍河網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:劍河等地區(qū)。劍河做網(wǎng)站價格咨詢:13518219792
在python中,類型屬于對象,變量是沒有類型的,這正是python的語言特性,也是吸引著很多pythoner的一點。所有的變量都可以理解是內(nèi)存中一個對象的“引用”,或者,也可以看似c中void*的感覺。所以,希望大家在看到一個python變量的時候,把變量和真正的內(nèi)存對象分開。
類型是屬于對象的,而不是變量。
這樣,很多問題就容易思考了。
例如:
對象vs變量
12
nfoo = 1 #一個指向int數(shù)據(jù)類型的nfoo(再次提醒,nfoo沒有類型)lstFoo = [1] #一個指向list類型的lstFoo,這個list中包含一個整數(shù)1
可更改(mutable)與不可更改(immutable)對象
對應(yīng)于上一個概念,就必須引出另了另一概念,這就是可更改(mutable)對象與不可更改(immutable)對象。
對于python比較熟悉的人們都應(yīng)該了解這個事實,在python中,strings, tuples, 和numbers是不可更改的對象,而list,dict等則是可以修改的對象。那么,這些所謂的可改變和不可改變影響著什么呢?
可更改vs不可更改
12345
nfoo = 1nfoo = 2lstFoo = [1]lstFoo[0] = 2
代碼第2行中,內(nèi)存中原始的1對象因為不能改變,于是被“拋棄”,另nfoo指向一個新的int對象,其值為2
代碼第5行中,更改list中第一個元素的值,因為list是可改變的,所以,第一個元素變更為2。其實應(yīng)該說,lstFoo指向一個包含一個對象的數(shù)組。賦值所發(fā)生的事情,是有一個新int對象被指定給lstFoo所指向的數(shù)組對象的第一個元素,但是對于lstFoo本身來說,所指向的數(shù)組對象并沒有變化,只是數(shù)組對象的內(nèi)容發(fā)生變化了。這個看似void*的變量所指向的對象仍舊是剛剛的那個有一個int對象的list。
如下圖所示:
Python的函數(shù)參數(shù)傳遞:傳值?引用?
對于變量(與對象相對的概念),其實,python函數(shù)參數(shù)傳遞可以理解為就是變量傳值操作,用C++的方式理解,就是對void*賦值。如果這個變量的值不變,我們看似就是引用,如果這個變量的值改變,我們看著像是在賦值。有點暈是吧,我們?nèi)耘f據(jù)個例子。
不可變對象參數(shù)調(diào)用
12345
def ChangeInt( a ): a = 10nfoo = 2 ChangeInt(nfoo)print nfoo #結(jié)果是2
這時發(fā)生了什么,有一個int對象2,和指向它的變量nfoo,當(dāng)傳遞給ChangeInt的時候,按照傳值的方式,復(fù)制了變量nfoo的值,這樣,a就是nfoo指向同一個Int對象了,函數(shù)中a=10的時候,發(fā)生什么?(還記得我上面講到的那些概念么),int是不能更改的對象,于是,做了一個新的int對象,另a指向它(但是此時,被變量nfoo指向的對象,沒有發(fā)生變化),于是在外面的感覺就是函數(shù)沒有改變nfoo的值,看起來像C++中的傳值方式。
可變對象參數(shù)調(diào)用
12345
def ChangeList( a ): a[0] = 10lstFoo = [2]ChangeList(lstFoo )print nfoo #結(jié)果是[10]
當(dāng)傳遞給ChangeList的時候,變量仍舊按照“傳值”的方式,復(fù)制了變量lstFoo 的值,于是a和lstFoo 指向同一個對象,但是,list是可以改變的對象,對a[0]的操作,就是對lstFoo指向的對象的內(nèi)容的操作,于是,這時的a[0] = 10,就是更改了lstFoo 指向的對象的第一個元素,所以,再次輸出lstFoo 時,顯示[10],內(nèi)容被改變了,看起來,像C++中的按引用傳遞。
函數(shù)參數(shù)傳遞機制問題在本質(zhì)上是調(diào)用函數(shù)(過程)和被調(diào)用函數(shù)(過程)在調(diào)用發(fā)生時進行通信的方法問題?;镜膮?shù)傳遞機制有兩
種:值傳遞和引用傳遞。
推薦:Python教程
值傳遞(passl-by-value)過程中,被調(diào)函數(shù)的形式參數(shù)作為被調(diào)函數(shù)的局部變量處理,即在堆棧中開辟了內(nèi)存空間以存放由主調(diào)函數(shù)放
進來的實參的值,從而成為了實參的一個副本。值傳遞的特點是被調(diào)函數(shù)對形式參數(shù)的任何操作都是作為局部變量進行,不會影響主調(diào)函
數(shù)的實參變量的值。
引用傳遞(pass-by-reference)過程中,被調(diào)函數(shù)的形式參數(shù)雖然也作為局部變量在堆棧中開辟了內(nèi)存空間,但是這時存放的是由主調(diào)函
數(shù)放進來的實參變量的地址。被調(diào)函數(shù)對形參的任何操作都被處理成間接尋址,即通過堆棧中存放的地址訪問主調(diào)函數(shù)中的實參變量。正
因為如此,被調(diào)函數(shù)對形參做的任何操作都影響了主調(diào)函數(shù)中的實參變量。
更多技術(shù)請關(guān)注Python視頻教程。
python的函數(shù)參數(shù)傳遞是"引用傳遞(地址傳遞)"。
python中賦值語句的過程(x = 1):先申請一段內(nèi)存分配給一個整型對象來存儲數(shù)據(jù)1,然后讓變量x去指向這個對象,實際上就是指向這段內(nèi)存(這里有點和C語言中的指針類似)。
在Python中,會為每個層次生成一個符號表,里層能調(diào)用外層中的變量,而外層不能調(diào)用里層中的變量,并且當(dāng)外層和里層有同名變量時,外層變量會被里層變量屏蔽掉。函數(shù)? 調(diào)用 ?會為函數(shù)局部變量生成一個新的符號表。
局部變量:作用于該函數(shù)內(nèi)部,一旦函數(shù)執(zhí)行完成,該變量就被回收。
全局變量:它是在函數(shù)外部定義的,作用域是整個文件。全局變量可以直接在函數(shù)里面應(yīng)用,但是如果要在函數(shù)內(nèi)部改變?nèi)肿兞?,必須使用global關(guān)鍵字進行聲明。
注意 :默認值在函數(shù)? 定義 ?作用域被解析
在定義函數(shù)時,就已經(jīng)執(zhí)行力它的局部變量
python中不可變類型是共享內(nèi)存地址的:把相同的兩個不可變類型數(shù)據(jù)賦給兩個不同變量a,b,a,b在內(nèi)存中的地址是一樣的。
def a(): global q q=1+2 return q def b(): a() c=2+q print(c) b()5 q3 函數(shù)中的變量在外面調(diào)用,需要申明為全局變量
def?plus(a,b):
z?=?a?+?1
c?=?b?+?5
return?(z,c)
(q,w)?=?plus(1,2)
plud(q,w)
##我這里假設(shè)a=1,b=2
##首先plus(1,2),得到z=2,c=7,通過return?讓(q,w)=(z,c)的值,然后plud(q,w)即可實現(xiàn)將z,c的值傳遞給下一個函數(shù)
對于可變參數(shù)默認是引用傳值, 但是不能去修改它的指向, 一旦修改就是按值傳遞.
#?coding=utf-8
def?f(a):
a?=?[0]
print(a)
if?__name__?==?'__main__':
a?=?[1,?2,?3]
f(a)
print(a)
上面的代碼對a重新賦值, 試圖改變a的指向, 那么這時的a就是一個新的局部變量, 而非全局變量a
像a[0] = 100, a.append(0)的操作不會觸發(fā)上述規(guī)則, 和你的輸出一樣
名稱欄目:python函數(shù)間傳數(shù)據(jù) python函數(shù)間參數(shù)傳遞
文章源于:http://muchs.cn/article12/hgsogc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、全網(wǎng)營銷推廣、移動網(wǎng)站建設(shè)、網(wǎng)站營銷、自適應(yīng)網(wǎng)站、標簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)