Python中變數傳遞時的引用和賦值

來源:互聯網
上載者:User
文章目錄
  • 例1:整數傳遞
  • 例2:變數傳遞
  • 例3:列表的地址儲存(以下為個人理解,未查原始碼,如有錯誤請指正)
  • 例4:列表傳遞(引用)
  • 例5:列表賦值
  • 例6:字典引用
  • 例7:字典賦值
  • 例8:不同類型變數傳遞

 Python中不明確區分賦值和應用,一般對靜態變數的傳遞為賦值,對動態變數的傳遞為引用。(注,對靜態變數首次傳遞時也是應用,當需要修改靜態變數時,因為靜態變數不能改變,所以需要產生一個新的空間儲存資料)個人覺得分清楚規則即可比較容易的區別。

字串,整數,元組均為靜態變數

列表,字典為動態變數。

以下樣本在Python 2.7環境下示範,id()函數可顯示變數記憶體位址

例1:整數傳遞

a = 4
print id(a) #id函數顯示變數記憶體位址
b = a
print id(b)
b = 6
print id(b)
>>>
19691376
19691376
19691328

說明,
1.a被賦值4
2.b是a的引用
3.b改變,因為此時b指向的是一個靜態變數4,所以給b賦值時,先將6存入一個和4不同的地址,然後b再指向6的地址

例2:變數傳遞

a = "mm"
print id(a)
b = a
print id(b)
b = "nn"
print id(b)
>>>
37313312
37313312
37313352

說明:

1.a為一個指向字串的變數名

2.a傳遞給b時,b為一個引用指向和a相同的地址

3.當b被賦給一個新字串值時,因為b指向的"mm"是一個靜態變數,所以產生一個新空間存放"nn",然後b指向"nn"

例3:列表的地址儲存(以下為個人理解,未查原始碼,如有錯誤請指正)

  1. a = [4, 5]
  2. print "address a=", id(a)
  3. print "address a0=", id(a[0])
  4. print "address a1=", id(a[1])
  5. b = a
  6. b[0] = 6
  7. print "a=", a
  8. print "b=", b
  9. print "address a=", id(a)
  10. print "address b=", id(b)
  11. print "address a0=", id(a[0])
  12. print "address a1=", id(a[1])
  13. b[1] = "str"
  14. print "a=", a
  15. print "b=", b
  16. print "address a=", id(a)
  17. print "address b=", id(b)
  18. print "address a0=", id(a[0])
  19. print "address a1=", id(a[1])

>>>

  1. address a= 24415912
  2. address a0= 23648112
  3. address a1= 23648088
  4. a= [6, 5]
  5. b= [6, 5]
  6. address a= 24415912
  7. address b= 24415912
  8. address a0= 23648064
  9. address a1= 23648088
  10. a= [6, 'str']
  11. b= [6, 'str']
  12. address a= 24415912
  13. address b= 24415912
  14. address a0= 23648064
  15. address a1= 140688190862360

說明:

從輸出的1,2,3行看出,a的地址>a[0]的地址>a[1]的地址,而且a[0]和a[1]地址間相差較遠,所以python中的列表絕對不是c中的數組,應該是個鏈表。(從python列表具有append()函數也可以看出)

命令第5行a傳遞給b時,從輸出6,7行看,a和b指向了同一個地址,b為a的一個引用,a,b的值應該是指向鏈表頭的指標。

命令第6行,b[0]值發生改變,從輸出4,5行看,a,b內容同時都發生改變,從輸出6,7行a,b指向的還是同一個地址,從輸出7行看a[0]的地址發生了改變,所以應該時鏈表的第一個節點被替換(即使變數類型相容),所以也可以理解為什麼python可以不關注變數類型。輸出第8行為a[1]的地址,沒有發生改變

命令第13行,b[1]被改變,分析同上,a,b指向的同一個鏈表的尾元素被替換

例4:列表傳遞(引用)

a = [4]
print id(a)
b = a
print id(b)
b[0] = 6
print id(b)
>>>
43351720
43351720
43351720

說明;

同上例理解

例5:列表賦值

a = [4]
print id(a)
b = a[:]
print id(b)
b[0] = 8
print id(b)
>>>
22863528
23030888
23030888

說明:

1.a指向一個動態變數列表

2.b得到a列表的一個copy儲存在一個新的空間,b指向一個新地址(b = a 和b=a[:]的區別可從 ,b=a,b=a[1:3]的區別進行理解)

3.b的第一個元素賦值8,不影響a

例6:字典引用

a = {"i":99}
print id(a)
b = a
print id(b)
b["o"] = 8
print id(b)
print "a=", a
print "b=", b
>>>
28841616
28841616
28841616
a= {'i': 99, 'o': 8}
b= {'i': 99, 'o': 8}

說明:

1.a指向一個動態變數

2.b為a的一個引用

3.b新增了一個變兩,a也新增

例7:字典賦值

a = {"i":99}
print id(a)
b = a.copy()
print id(b)
b["o"] = 8
print id(b)
print "a=", a
print "b=", b
>>>
16033424
16063424
16063424
a= {'i': 99}
b= {'i': 99, 'o': 8}

說明:

1.a指向一個動態變數

2.b為a的一個拷貝,指向一個新地址

3.b新增了一個變數,a不變

例8:不同類型變數傳遞

a = "mm"
print id(a)
b = a
print id(b)
b = 8
print id(b)
print "a=", a
print "b=", b

>>>

11687096
11687096
10692368
a= mm
b= 8

說明:

1.a指向一個靜態

2.b為a的一個應用,指向和a相同的地址

3.b發生了改變,指向一個新的資料地址

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.