1. 程式人生 > >python:函式傳參是否會改變函式外引數的值

python:函式傳參是否會改變函式外引數的值

參考連結:

https://blog.csdn.net/u012614287/article/details/57149290

https://blog.csdn.net/qq915697213/article/details/66972836

1、介紹python函式傳參

  1. Python不允許程式設計師選擇採用傳值還是傳引用。Python引數傳遞採用的肯定是“傳物件引用”的方式。實際上,這種方式相當於傳值和傳引用的一種綜合。如果函式收到的是一個可變物件(比如字典或者列表)的引用,就能修改物件的原始值——相當於通過“傳引用”來傳遞物件。如果函式收到的是一個不可變物件(比如數字、字元或者元組)的引用,就不能直接修改原始物件——相當於通過“傳值”來傳遞物件。

  2. 當人們複製列表或字典時,就複製了物件列表的引用同,如果改變引用的值,則修改了原始的引數。

  3. 為了簡化記憶體管理,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則會;