python引數傳遞

2021-08-21 10:00:00 字數 1652 閱讀 8080

當我們在python中使用等號給陣列賦值的時候往往會出現乙個問題

a = [1, 2, 3]

b = a

print("a陣列為:",a)

# a陣列為: [1, 2, 3]

print("b陣列為:",b)

# b陣列為: [1, 2, 3]

正常我們這樣使用是沒有任何問題的,但是如果我們將原陣列 a 進行改變pop出乙個棧頂元素

a.pop()

# out[6]: 3

print("b陣列為:",b)

# b陣列為: [1, 2]

我們發現 b 陣列也改變了,可是我們明明改動的是 a 陣列,這是為什麼呢?

因為在 python 中 「=」傳遞的是位址而不是值,所以實際上 b=a 的操作只是將a的位址傳給了b,所以改動了值,無論誰來讀取都是一樣的改變了。

如果我們想完全複製乙個互不影響的陣列應該怎麼辦呢?

a = [1, 2, 3]

b[:] = a

a.pop()

# out[6]: 3

print("b陣列為:",b)

# b陣列為: [1, 2, 3]

我們使用 b[:] 的方式 就相當於把 a 陣列的每乙個元素對應的拷貝到 b 中去所以就另開了一塊空間儲存,這時的a ,b是互不影響的。

這裡涉及到乙個知識點就是python引數引用的問題(傳值\傳位址)

如果函式收到的是乙個可變物件(比如字典或者列表)的引用,就能修改物件的原始值——相當於傳址。如果函式收到的是乙個不可變物件(比如數字、字元或者元組)的引用,這時就不能直接修改原始物件的值,所以這時候相當於值傳遞。這也就可以解釋為什麼 [:]可以直接接收到值傳遞,因為沒有[:]的時候傳遞的是一整個list的位址,加上了[:]表示的傳遞的是list中的不可變物件,因此變成了值傳遞。

所以python的傳值和傳址是根據傳入引數的型別來選擇的

傳值的引數型別:number,str,tuple

傳址的引數型別:list,dict

其實正常我們想要實現複製乙個值相等的物件的時候,常用的辦法是 copy 和 deepcopy

import copy

a=[1,2,3]

b=copy.copy(a)

a.pop()

print(a,b)

# [1, 2, 3, 4] [1, 2, 3]

我們可以看到使用copy的方法也是可以實現這種複製的,此時a與b值相同位址不同,修改一方不會互相影響,但是當我們複製的物件中存在複雜型別的時候,我們再來看一下

a=[[1,1],2,3]

b=copy.copy(a)

print(a,b)

# [[1,1], 2, 3] [[1,1], 2, 3]

夭壽了!我們發現又不好使了,面對這種複雜資料型別的時候就要輪到我們的deepcopy出場了

a=[[1,1],2,3]

b=copy.deepcopy(a)

print(a,b)

# [[1,1,1], 2, 3] [[1,1], 2, 3]

easy as a pie, mission complete!!

python 引數傳遞 Python 引數傳遞

python中的變數 乙個變數是區域性還是全域性,在編譯函式的時候就已經決定,因此讀變數值的時候也不會逐層向外查詢。變數是全域性還是局域,根據如下3條 1.如果函式內部有global語句,那麼它宣告的變數是全域性的。2.如果函式內部有對變數的賦值語句,那麼它是局域的。3.除此之外都是全域性的。注意1...

python 引數傳遞 python引數傳遞

python中函式引數的傳遞是通過 賦值 來傳遞的。但這條規則只回答了函式引數傳遞的 戰略問題 並沒有回答 戰術問題 也就說沒有回答怎麼賦值的問題。函式引數的使用可以分為兩個方面,一是函式引數如何定義,二是函式在呼叫時的引數如何解析的。而後者又是由前者決定的。函式引數的定義有四種形式 1.f arg...

python變數傳遞 Python引數傳遞

在 python 中,型別屬於物件,變數是沒有型別的 a 1,2,3 a runoob 以上 中,1,2,3 是 list 型別,runoob 是 string 型別,而變數 a 是沒有型別,她僅僅是乙個物件的引用 乙個指標 可以是指向 list 型別物件,也可以是指向 string 型別物件。可更...