python函數參數改變問題


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]
  • 函數體傳入的參數 , 為函數體外變量引用的副本 .
  • 在函數體中改變變量指向的堆中的值 , 對函數外變量有效.
  • 在函數體中改變變量的引用 , 對函數外變量無效

要想不改變原list,用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]

要想改變bool型,將其作為返回值

  1. flag不做返回值,函數外不發生改變
flag=True
def change2(list,flag):
    list.append(34)
    flag=False

mylist = ["aa",21]
print mylist
change2(mylist,flag)
print mylist,flag

結果:

['aa', 21]
['aa', 21, 34] True

  1. flag作為返回值,返回值可用,但函數仍然不發生改變
flag=True
def change2(list,flag):
    list.append(34)
    flag=False
    return flag

mylist = ["aa",21]
print mylist
print change2(mylist,flag)
print mylist,flag

輸出結果:

['aa', 21]
False
['aa', 21, 34] True


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM