python:函式傳參是否會改變函式外引數的值
參考連結:
https://blog.csdn.net/u012614287/article/details/57149290
https://blog.csdn.net/qq915697213/article/details/66972836
1、介紹python函式傳參
Python不允許程式設計師選擇採用傳值還是傳引用。Python引數傳遞採用的肯定是“傳物件引用”的方式。實際上,這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是一個可變物件(比如字典或者列表)的引用,就能修改物件的原始值——相當於通過“傳引用”來傳遞物件。如果函式收到的是一個不可變物件(比如數字、字元或者元組)的引用,就不能直接修改原始物件——相當於通過“傳值”來傳遞物件。
當人們複製列表或字典時,就複製了物件列表的引用同,如果改變引用的值,則修改了原始的引數。
為了簡化記憶體管理,Python通過引用計數 機制實現自動垃圾回收功能,Python中的每個物件都有一個引用計數,用來計數該物件在不同場所分別被引用了多少次。每當引用一次Python物件,相應的引用計數就增1,每當消毀一次Python物件,則相應的引用就減1,只有當引用計數為零時,才真正從記憶體中刪除Python物件。
上面也就是說,當我們傳的引數是int、字串(string)、float、(數值型number)、元組(tuple) 時,無論函式中對其做什麼操作,都不會改變函式外這個引數的值;
當傳的是字典型(dictionary)、列表型(list)時,如果是重新對其進行賦值,則不會改變函式外引數的值,如果是對其進行操作,則會改變。
即變數中儲存的是引用 , 是指向真正內容的記憶體地址 , 對變數重新賦值 , 相當於修改了變數副本儲存的記憶體地址 , 而這時的變數已經和函式體外的變數不是同一個了, 在函式體之外的變數 , 依舊儲存的是原本的記憶體地址 , 其值自然沒有發生改變 。
簡單來說 :
- 函式體傳入的引數 , 為函式體外變數引用的副本 .
- 在函式體中改變變數指向的堆中的值 , 對函式外變數有效.
- 在函式體中改變變數的引用 , 對函式外變數無效
2、程式碼舉例子
2.1 字串
def get(s1, s2):
s1 = s1 + "haha"
s2 = "haha"
s1 = "abc"
s2 = "abc"
print s1, s2
get(s1, s2)
print s1, s2
可以看出,沒有發生變化
2.2 整型
def nunm(a, b):
a = a + 1
b = 3
a = 9
b = 9
print a, b
nunm(a, b)
print a, b
可以看到也沒餘發生變化
2.3 list
def lists(l1, l2):
l1.append(1)
l2 = [1, 2, 3]
list1 = [9, 8, 7]
list2 = [9, 8, 7]
print list1, list2
lists(list1, list2)
print list1, list2
可以看到,重新賦值後不會對原引數造成改變,但是append則會;