在編程語言中,函數的參數傳遞有兩種狀況:python
num = 10
def double(arg):
arg=arg*2
print(arg)
double(num)
複製代碼
調用該函數,傳入一個變量,其實傳入的是該變量的一個副本,該變量在函數中發生變化,不影響函數外面該變量。編程
def change(arg):
arg.append('More data')
print(arg)
saying = [42,34,55]
change(saying)
複製代碼
調用該函數,傳入一個變量,可是函數內部倒是維護該變量的一個指向連接,連接到函數外面的這個變量;當傳入函數的這個變量在函數內部發生改變,直接影響到外面的最初變量,由於有指向關係。bash
python
中的函數參數既支持按值調用,也支持按引用調用。app
python中的變量是對象引用
:變量存儲的值是內存地址。當函數被調用的時候,解釋器會查看傳入的變量(內存地址)指的那個指的類型,若是是一個可變類型
的值,就按照引用傳遞變量;若是是一個非可變類型
的值,就考慮按照值傳遞變量。編程語言
可變類型
:字典dict
,列表list
,集合set
:函數
傳入函數中的變量,函數內部的修改都會反映到函數外面,即最初始的變量會受到影響,畢竟這些初始的變量是可變類型。ui
不可變類型
:字符串srt
,整數int
,元組trulp
:spa
在這中,函數對變量的任何修改都是函數私有的,不會反映到函數外面,因爲這些變量是不可變的,因此不能修改。3d
例外:code
def double(arg):
print('before: ',arg)
arg = arg * 2
print('After: ',arg)
複製代碼
根據上面所說的,爲何這個函數裏面的參數,傳入的一個可變類型,函數內部發生了改變,結果卻沒有反映到函數外面呢?
咱們考慮到這條語句:arg = arg*2
首先,傳入的變量,先執行arg*2
,所產生的新的變量(新對象的引用),從新賦值給原先的變量arg
,覆蓋其原先的引用,致使原先的變量arg
與外面初始變量之間的聯繫斷了。既然關係斷了,那麼函數裏面的arg
的改變,沒有反映出來,因此並無影響到函數外面的變量。