介紹引用傳遞
python只允許使用引用傳遞
, 不存在其他語言中的值傳遞颤介。引用傳遞即引用內(nèi)存地址
梳星, 無論是賦值還是函數(shù)調(diào)用。
不可變對象
不可變對象指向內(nèi)存地址的值不能夠被改變买窟, 這些對象包含int,string,float,tuple
丰泊。
i = 1
j = i
print('id is %s for i' % id(i))
print('id is %s for j' % id(j))
print(i, j)
j = j + 1
print('id is %s for i' % id(i))
print('id is %s for j' % id(j))
print(i, j)
#result
id is 11061440 for i
id is 11061440 for j
1 1
id is 11061440 for i
id is 11061472 for j
1 2
- 最初 i 賦值給 j 時是
引用傳遞
薯定, 它們的內(nèi)存地址都是11061440始绍, 即 i 和 j 指向同一個內(nèi)存地址 - 后面當(dāng)對象 j 被改變時, 由于所指向的內(nèi)存中的值不能被改變话侄, 所以會復(fù)制一份值到新的地址再處理計算(+1)亏推, 然后對象 j 指向新的地址11061472
不可變對象
可變對象
可變對象指向內(nèi)存地址的值直接被改變学赛, 這些對象包含list,dict,set
。
a = [1]
b = a
print('id is %s for a' % id(a))
print('id is %s for b' % id(b))
print(a, b)
b[0] = 0
print('id is %s for a' % id(a))
print('id is %s for b' % id(b))
print(a, b)
#result
id is 140198854737480 for a
id is 140198854737480 for b
[1] [1]
id is 140198854737480 for a
id is 140198854737480 for b
[0] [0]
- 最初 a 賦值給 b 時是
引用傳遞
吞杭, 它們的內(nèi)存地址都是140198854737480盏浇, 即 a 和 b 指向同一個內(nèi)存地址 - 后面當(dāng)對象 b 被改變時, 由于所指向的內(nèi)存中的值直接被改變芽狗, 發(fā)現(xiàn)改變b的同時a也被改變了绢掰, 但是 a 和 b 還是指向同一個內(nèi)存地址
可變對象
函數(shù)的參數(shù)傳遞也分可變和不可變對象的
def test_para(a, b):
a += 1
b[0] = 0
print('========1111111111==============')
print('a is %s and the id is %s.' % (a, id(a)))
print('b is %s and the id is %s.' % (b, id(b)))
a = 1
b = [1]
print('a is %s and the id is %s.' % (a, id(a)))
print('b is %s and the id is %s.' % (b, id(b)))
test_para(a, b)
print('========22222222222==============')
print('a is %s and the id is %s.' % (a, id(a)))
print('b is %s and the id is %s.' % (b, id(b)))
#result
a is 1 and the id is 11061440.
b is [1] and the id is 139909172055624.
========1111111111==============
a is 2 and the id is 11061472.
b is [0] and the id is 139909172055624.
========22222222222==============
a is 1 and the id is 11061440.
b is [0] and the id is 139909172055624.
- 當(dāng)傳過來的是
可變對象
,函數(shù)內(nèi)部修改會影響
函數(shù)外部的可變對象童擎。 - 當(dāng)傳過來的是
不可變對象
滴劲,函數(shù)內(nèi)部修改不會影響
函數(shù)外部的不可變對象,因為修改的時候會先復(fù)制一份再修改
def test_para(b=[]):
b += [0]
print('b is %s and the id is %s.' % (b, id(b)))
test_para()
test_para()
test_para()
test_para([1, 2, 3])
#result
b is [0] and the id is 140394154311240.
b is [0, 0] and the id is 140394154311240.
b is [0, 0, 0] and the id is 140394154311240.
b is [1, 2, 3, 0] and the id is 140394177812936.
- Python 解釋器執(zhí)行 def 語句時顾复, 會創(chuàng)建一個
函數(shù)對象
班挖, 且只會有一個 - 默認參數(shù) b 就已經(jīng)計算出來, 指向了
[] 空列表
- 第一次調(diào)用test_para()時芯砸, 往b中添加一個值為1的元素
- 第二次萧芙,第三次調(diào)用test_para()時, 繼續(xù)往b中添加一個值為1的元素假丧,
用了同一個對象b双揪, 指向同一個內(nèi)存地址
- 當(dāng)調(diào)用test_para([1, 2, 3])時, b 被
重新賦值
包帚, b指向了[1, 2, 3]的新地址
list中的注意事項
- 對象被
重新賦值
a = a + [3] 或者 a = [3] 都是重新被賦值盟榴, 但是 a += [3]不是的,相當(dāng)于a.extend([3])
a = b = [1, 2]
print(a, id(a), b, id(b))
a = a + [3]
print(a, id(a), b, id(b))
#result
[1, 2] 140607382289992 [1, 2] 140607382289992
[1, 2, 3] 140607405791752 [1, 2] 140607382289992
a = b = [1, 2]
print(a, id(a), b, id(b))
a += [3]
print(a, id(a), b, id(b))
#result
[1, 2] 140479908183624 [1, 2] 140479908183624
[1, 2, 3] 140479908183624 [1, 2, 3] 140479908183624
a = b = [1, 2]
print(a, id(a), b, id(b))
a = [3]
print(a, id(a), b, id(b))
#result
[1, 2] 139779074858568 [1, 2] 139779074858568
[3] 139779098360264 [1, 2] 139779074858568
a = [1, 2]
s = [a] * 2
print(s, id(s[0]), id(s[1]))
a.append(3)
print(s, id(s[0]), id(s[1]))
a[0] = 0
print(s, id(s[0]), id(s[1]))
s[0] = [0]
print(s, id(s[0]), id(s[1]))
#result
[[1, 2], [1, 2]] 139773557825096 139773557825096
[[1, 2, 3], [1, 2, 3]] 139773557825096 139773557825096
[[0, 2, 3], [0, 2, 3]] 139773557825096 139773557825096
[[0], [0, 2, 3]] 139773581326792 139773557825096
- 如何
復(fù)制list的值
婴噩,但不指向同一個地址
一階列表
和高階列表
有很大區(qū)別擎场, 一階列表可以使用a[:], list(a), a.copy(), copy.copy(a), copy.deepcopy(a)
等方法拷貝一份, 而高階列表只能使用copy.deepcopy(a)
深度拷貝一份
import copy
a = [0, 1]
b = 3
num = [a, b]
print('num is %s and id is %s\n' % (num, id(num)))
c = num[:]
d = list(num)
e = num.copy()
f = copy.copy(num)
g = copy.deepcopy(num)
print('c is %s and id is %s\n' % (c, id(c)),
'd is %s and id is %s\n' % (d, id(d)),
'e is %s and id is %s\n' % (e, id(e)),
'f is %s and id is %s\n' % (f, id(f)),
'g is %s and id is %s\n' % (g, id(g))
)
print('-------------------------------------------')
a.append(2)
print('num is %s and id is %s\n' % (num, id(num)))
print('c is %s and id is %s\n' % (c, id(c)),
'd is %s and id is %s\n' % (d, id(d)),
'e is %s and id is %s\n' % (e, id(e)),
'f is %s and id is %s\n' % (f, id(f)),
'g is %s and id is %s\n' % (g, id(g))
)
#result
num is [[0, 1], 3] and id is 140319229340360
c is [[0, 1], 3] and id is 140319229131848
d is [[0, 1], 3] and id is 140319229219464
e is [[0, 1], 3] and id is 140319229219016
f is [[0, 1], 3] and id is 140319229219784
g is [[0, 1], 3] and id is 140319229220232
-------------------------------------------
num is [[0, 1, 2], 3] and id is 140319229340360
c is [[0, 1, 2], 3] and id is 140319229131848
d is [[0, 1, 2], 3] and id is 140319229219464
e is [[0, 1, 2], 3] and id is 140319229219016
f is [[0, 1, 2], 3] and id is 140319229219784
g is [[0, 1], 3] and id is 140319229220232