標籤:

python 函數中傳值,傳的是引用還是複製一份傳給另一個函數,會修改調用函數裡面的值嘛?


說得具體點可以把python的變數理解成一個名字指向實際的值,在傳到函數里的時候, 是告訴函數的變數名字也指向我的這個值,但是並不是我自己傳到函數內

比如foo = [1,2,3] 可以理解成為foo指向[1,2,3],foo和[1,2,3]並不是在一起

現在有個函數

def alter(bar):
bar.append(4)
bar = [0,1]

如果我們把foo傳給alter這個函數,

alter(foo)

就會有foo和bar分別指向[1,2,3]

執行bar.append(4)

因為bar指向[1,2,3], [1,2,3]現在變成[1,2,3,4]

因為foo也指向[1,2,3],現在被bar改成了[1,2,3,4],foo也是[1,2,3,4]

執行bar = [0,1]

bar指向一個新的[0,1],但是foo還是指向[1,2,3,4]

運行完alter函數foo是[1,2,3,4]

所以理論上不是傳引用,如果穿引用foo在執行完alter函數後應該是[0,1]

下面是完整測試代碼

def alter(bar):
bar.append(4)
bar = [0,1]

foo = [1,2,3]
print "foo", foo
alter(foo)
print "foo", foo


傳的是引用,但是相同引用的一個複本。


對於Python這塊很奇怪的東西,我覺得用指針來解釋比較合適吧。

def alter(bar):
bar.append(4)
bar = [0,1]

foo = [1,2,3]
print "foo", foo
alter(foo)
print "foo", foo

輸出結果分別是[1,2,3] [1,2,3,4]

其實傳入的list set都是傳了一個這個類型的地址值進去,append是修改了指向的東西,bar = [0, 1]

相當於函數內的指針變數指向了一個新的list,而不影響外部list的值

因此foo = [1,2,3] 可以理解成foo這個指針變數指向了一個新生成的list

這裡用值傳遞不合適,因為裡面append 會修改外部的list值

用引用傳遞也不合適,因為裡面bar = [0, 1] 又不會影響外部list的值

所以用指針傳遞好像兩邊都說得通


可變對象傳的是引用,不可變對象可以看做傳值


複製一份PyObject *但是PyObject 不複製


推薦閱讀:

Mixin是什麼概念?
關於 Python 字典的 values() 方法返回值的順序?
如何學習 Python,面對那麼多的標準庫,應該如何?
Python 在改代碼時怎麼處理縮進問題?
簡歷中如何證明自己的編程能力?

TAG:Python |