1. 程式人生 > >python函數參數改變問題

python函數參數改變問題

改變 java dict 修改 影響 變化 原來 ava 內部

python函數參數改不改變的問題

前幾天在做項目的過程中發現了一個問題,向函數中傳入一個list,在函數體內將其賦值給list,對list1操作後發現list也發生了變化,啊 ! 出乎意料。查了一下原因,原來python裏有可變對象和不可變對象之分。只有傳入的是不可變對象時,值才不發生改變,若是可變對象,充當函數參數時要註意了。

不可變對象:Number ,String , Tuple,bool
可變對象: List , Set , Dictionary是可以改變內部的元素

下面總結一下:

先看例子:

def changestr (str):
    str = "inside"
    print "這是function中 , 值為:",str
mystr = "outside"
changestr(mystr)
print "這是函數外邊 , 值為:",mystr

輸出結果:

這是function中 , 值為: inside
這是函數外邊 , 值為: outside

即 傳入不可變對象字符串,在函數內對其操作不影響調用結束後字符串的值,即不發生改變。

ps: Number和Tuple結果是一樣的,這三種類型只能通過重新賦值來改變對象的值 .

def changestr (str):
    str.append(3)
    print "這是function中 , 值為:",str
mystr = [1,2]
changestr(mystr)
print "這是函數外邊 , 值為:",mystr

結果:

這是function中 , 值為: [1, 2, 3]
這是函數外邊 , 值為: [1, 2, 3]
  • 對於可變對象,在函數體中的修改 , 對對象本身的值發生了改變 , 在函數之外 , 該列表的內容依然發生了改變 , 這是事先就能猜測到的結果 , 因為python中的參數 , 傳入的是變量引用的副本 , 它與變量指向同一個值.

3


def change2(list):
    list = [1,2,3,4]
mylist = ["aa",21]
print(mylist)
change2(mylist)
print(mylist)

輸出結果:


[‘aa‘, 21]
[‘aa‘, 21]

可變對象在函數體中的重新賦值 , 沒有對外部變量的值產生影響 , 不過仔細一想 , 卻又在情理之中 .

  • 即變量中存儲的是引用 , 是指向真正內容的內存地址(當然 ,java中的八大基本數據類型 , 變量名和值都是存儲在堆棧中的 ) , 對變量重新賦值 , 相當於修改了變量副本存儲的內存地址 , 而這時的變量已經和函數體外的變量不是同一個了, 在函數體之外的變量 , 依舊存儲的是原本的內存地址 , 其值自然沒有發生改變 .

3

def change2(list):
    list1 =list
    list1.append(34)
mylist = ["aa",21]
print mylist
change2(mylist)
print mylist

輸出結果:


[‘aa‘, 21]
[‘aa‘, 21, 34]
  • 函數體傳入的參數 , 為函數體外變量引用的副本 .
  • 在函數體中改變變量指向的堆中的值 , 對函數外變量有效.
  • 在函數體中改變變量的引用 , 對函數外變量無效

要想不改變yuanlist,用copy.deepcopy()


import copy
def change2(list):
    list1=copy.deepcopy(list)
    list1.append(34)
mylist = ["aa",21]
print mylist
change2(mylist)
print mylist

結果:

[‘aa‘, 21]
[‘aa‘, 21]

python函數參數改變問題