文章目錄
- 例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:列表的地址儲存(以下為個人理解,未查原始碼,如有錯誤請指正)
- a = [4, 5]
- print "address a=", id(a)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
- b = a
- b[0] = 6
- print "a=", a
- print "b=", b
- print "address a=", id(a)
- print "address b=", id(b)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
- b[1] = "str"
- print "a=", a
- print "b=", b
- print "address a=", id(a)
- print "address b=", id(b)
- print "address a0=", id(a[0])
- print "address a1=", id(a[1])
>>>
- address a= 24415912
- address a0= 23648112
- address a1= 23648088
- a= [6, 5]
- b= [6, 5]
- address a= 24415912
- address b= 24415912
- address a0= 23648064
- address a1= 23648088
- a= [6, 'str']
- b= [6, 'str']
- address a= 24415912
- address b= 24415912
- address a0= 23648064
- 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發生了改變,指向一個新的資料地址