這個問題的答案無外乎這幾種說法:傳值,傳引用,對于可變對象是傳引用,不可變對象是傳值。
10余年的藍山網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調整藍山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)建站從事“藍山網(wǎng)站設計”,“藍山網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
傳引用
先看下面這個例子:
def foo(n):
... print id(n)
... n = 3
... print id(n)
n = 2
id(n)
31030000L
foo(n)
31030000L
31029976L
n
2
id(n)
31030000L
由foo中兩次輸出不相等可以看出,傳引用說法并不成立。
傳值
來看下面的例子:
def foo(n):
... print n
... n.append(3)
... print n
n = [1, 2, 4, 8]
foo(n)
[1, 2, 4, 8]
[1, 2, 4, 8, 3]
n
[1, 2, 4, 8, 3]
按傳值的說法,一個值傳進來,在函數(shù)內改動并不會影響變量本身的值,上面例子中n變量本身的值也被改變了,說明傳值的說法也不對。
3.可變對象傳引用,不可變對象傳值
相比上面兩種說法,這種說法似乎更靠譜,傳播也更為廣泛,那它到底對不對呢?
def foo(n):
... print id(n)
... n = ['1', '2', '3']
... print id(n)
... print n
n = [1,2,3,4,5,6]
id(n)
35637576
foo(n)
35637576
35916168
['1', '2', '3']
n
[1, 2, 3, 4, 5, 6]
按照可變對象傳引用的說法,上面list類型是可變對象,應該傳引用,這foo方法中兩次調用id應該輸出一樣的值,更改的結果也應該影響到外部變量,但結果顯然不是這樣的,這說明,這種說法也是不正確的。
那么Python傳值的方法到底是什么樣呢?其實Python中的函數(shù)參數(shù)所遵循的是傳對象(call by object),或者叫做穿對象的引用(call by object reference)。在調用函數(shù)時,將變量整個對象傳入,對于可變對象的修改,在函數(shù)內外均可見;而對于不可變對象,因為其并不能真正意義上被賦值,修改是通過生成新的對象來實現(xiàn)的。
下面來一個有趣的例子作為結尾:
def bar(a = []):
... print id(a)
... a.append(7)
... print a
for _ in range(5):
... bar()
#結果輸出請自己動手實踐,原因應該不難理解
那要看數(shù)據(jù)類型了,int,float,str這種就是傳值,list,dict,類的實例,自定義對象都是穿引用。
下面是示例代碼:
def?change(int1,float1,str1,dict1,obj1,list1):
int1+=1
float1+=1
str1+='changed'
dict1['none_exist_key']='none_exist_value'
obj1=None
list1.append('change')
class?obj:
pass
int1=0
float1=0.0
str1='origin'
dict1={'key':'value'}
obj1=obj()
list1=['only_element']
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)
change(int1,float1,str1,dict1,obj1,list1)
print('after?change')
print(int1)
print(float1)
print(str1)
print(dict1)
print(obj1)
print(list1)
不明白可追問
python的一切數(shù)據(jù)類型都是對象。但是python的對象分為不可變對象和可變對象。python的變量是引用,對python變量的賦值是引用去綁定該對象。
可變對象的數(shù)據(jù)發(fā)生改變,例如列表和字典,引用不會更改綁定對象,畢竟本身就是用于增刪改查的,頻繁地產生新對象必然導致開銷巨大,只需要該對象內部變化就行;但對于綁定了不可變對象的引用,對象一旦改變就會使引用綁定新的對象。
這一點也會反應到函數(shù)的參數(shù)上。python的傳值方式是“傳對象”引用。python的函數(shù),形參實際上是引用,實參便是對象綁定到該引用上。本質是形參會被作為函數(shù)的局部變量,在開辟的函數(shù)的棧內存中被聲明。
簡要來講:
如果參數(shù)是數(shù),則類似值傳遞,
如果參數(shù)是列表和字典,則類似引用傳遞。
每個對象都會有個id, 可以用id()驗證以上說法:
這個函數(shù)的參數(shù)是列表,是可變對象。
首先你要明白,Python的函數(shù)傳遞方式是賦值,而賦值是通過建立變量與對象的關聯(lián)實現(xiàn)的。
對于你的代碼:
執(zhí)行 d = 2時,你在__main__里創(chuàng)建了d,并讓它指向2這個整型對象。
執(zhí)行函數(shù)add(d)過程中:
d被傳遞給add()函數(shù)后,在函數(shù)內部,num也指向了__main__中的2
但執(zhí)行num = num + 10之后,新建了對象12,并讓num指向了這個新對象——12。
如果你明白函數(shù)中的局部變量與__main__中變量的區(qū)別,那么很顯然,在__main__中,d仍在指著2這個對象,它沒有改變。因此,你打印d時得到了2。
如果你想讓輸出為12,最簡潔的辦法是:
在函數(shù)add()里增加return num
調用函數(shù)時使用d = add(d)
代碼如下:
def add(num):
num += 10
return num
d = 2
d = add(d)
print d
新聞標題:python傳值函數(shù)嗎 python 類之間傳值
網(wǎng)站URL:http://www.rwnh.cn/article14/doohsge.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、微信小程序、、做網(wǎng)站、網(wǎng)站建設、移動網(wǎng)站建設
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)