開門見山,python內傳值方式都是引用傳遞。
python內所有變數分類可變變數和不可變變數:
可變變數:列表、字典、可變集合(set)
不可變變數:數字、字串、元組、不可變集合(frozenset)
理解了以上概念之後,下面深入**一下python的傳值方式。
python宣告的所有變數都是以物件的形式存放在記憶體中。對於不可變變數,如字串『abc』,python在記憶體中會有一塊記憶體區域來存放,這塊記憶體區域的起始位址可以理解為對該變數的引用。所有的不可變變數在記憶體中只有乙份,它是通過引用計數器來記住有多少變數引用到了此不可變變數。如:
import sys
str1 = 'abc'
str2 = 'abc'
print(str1 == str2)
print(id(str1)) # 檢視str1變數,即abc的儲存位址
print(id(str2)) # 檢視str2變數,即abc的儲存位址
print(str1 is str2) # str1和str2是否乙個位址
print(sys.getrefcount('abc')) # 檢視對abc的引用計數器
# str1和str2都被賦值為不可變變數,在記憶體中只有乙個區域存放了字串'abc',但是對這塊區域的引用計數是2以上(最少為2,多出的部分可能是系統底層引用,這塊我沒有深入研究)
# 輸出:
true
5795432
5795432
true
37
上面可見,對於不可變變數的多次引用實質上都是增加了引用計數器,其記憶體位址是同乙個。那麼當把str2的值改為'def'時,str2的引用不再是'abc'的位址,而變成'def'的位址,此時系統會在記憶體空間中開闢出一塊記憶體來存放'def'並把這塊的首位址給str2。
綜上,不可變變數在python中只有乙個,但是依靠引用計數器來實現多個變數對它的引用。
對於可變變數則不同,由於變數是可變的,在程式執行中可能隨時會發生變化,那麼只設定乙個記憶體區域存放,依靠引用計數器來實現對變數的多個引用就變得不現實。因此,對可變變數,策略是乙個蘿蔔乙個坑,每定義乙個可變變數,就開闢乙個可變變數的記憶體空間存放此變數。
str1 =
str2 =
print(str1 == str2)
print(id(str1))
print(id(str2))
print(str1 is str2)
# 輸出:
true
61522440
61522504
false
可以看到,同樣是定義兩個空list,但是這兩個list的位址不同。這就帶來了乙個問題,函式傳參時,如果實參和形參為不可變變數,那麼從實參傳遞到形參的引用指向的是一塊不可變變數的記憶體區域,當在函式內對形參修改時,形參引用了其他的物件(無所謂是否可變變數),而外層的實參仍引用著最開始的不可變變數。這就給人感覺一種不可變變數是值傳遞的錯覺(其實這裡形參和實參已經是兩個不同的變數了)。相反,若傳遞的是乙個可變變數,實參傳遞給形參的是乙個可變變數的記憶體位址,那麼在函式內部對這個可變變數做修改,其實是在對這片記憶體區域做修改,函式返回時,實參同樣引用著這塊區域,故實參也會發生變化(這裡實參和形參也是兩個變數,這兩個變數值相等,都是同一塊位址。可以理解為指向指標的指標)。 Vue傳值方式
1.provide和inject實現祖先與後代元件傳值 祖先元件 export default provide 後代元件 export default 2.props實現父向子傳值 父元件 zhnagsan age 2 子元件 export default 3.emit實現子元件傳資料給父元件 子元...
Vue傳值方式
父傳子 1.1父元件準備資料 1.2給子元件註冊定義屬性 1.3子元件用props接收資料 注意 這裡我監聽了 父元件的值 子傳父 2.1 子元件準備資料 this.cstcde和thi.danme已經在子元件data中定義好了 2.2 子元件需要觸發自定義事件,觸發事件傳遞引數 confirm就是...
C 引用方式傳參,傳值方式傳參( )
1 引用方式傳參 引用相當於是外部變數的別名,實際操作的就是該變數,即在函式內對該變數進行修改的話,在外部該變數也會相應被修改。外部變數的值也會被修改 void changeref int ref 2 傳值方式傳參 實際上是複製了乙個外部變數的副本進入函式中,在函式內操作的為該副本,對該變數的修改並...