作爲一個python初學者,今天被一個python列表和詞典引用的問題折磨了很久,但其實瞭解了緣由也很簡單,記錄在此備忘。
首先背書python中的引用對象問題:
1. python不允許程序員選擇採用傳值還是傳引用。Python參數傳遞採用的肯定是“傳對象引用”的方式。實際上,這種方式相當於傳值和傳引用的一種綜合。如果函數收到的是一個可變對象(比如字典或者列表)的引用,就能修改對象的原始值——相當於通過“傳引用”來傳遞對象。如果函數收到的是一個不可變對象(比如數字、字符或者元組)的引用,就不能直接修改原始對象——相當於通過“傳值'來傳遞對象。
2. 當人們複製列表或字典時,就複製了對象列表的引用同,如果改變引用的值,則修改了原始的參數。
3. 爲了簡化內存管理,Python通過引用計數機制實現自動垃圾回收功能,Python中的每個對象都有一個引用計數,用來計數該對象在不同場所分別被引用了多少次。每當引用一次Python對象,相應的引用計數就增1,每當消毀一次Python對象,則相應的引用就減1,只有當引用計數爲零時,才真正從內存中刪除Python對象
首先,我們來了解一下python的基礎概念:
1. Python在heap中分配的對象分成兩類:可變對象和不可變對象。所謂可變對象是指,對象的內容是可變的,例如list。而不可變的對象則相反,表示其內容不可變。
不可變對象:int,string,float,tuple
可變對象 :list,dictionary
2. Python函數的參數傳遞採用的是“傳對象引用”的方式。
下面我們用例子來理解一下以上概念:
- x=1
- y=x #y跟x指向同一個對象引用
- x=2 #由於x是不可變對象,這時候舊的對象被系統回收,x指向新的對象引用
- print x,y #結果是2,1
- a = ['1'] #a指向了一個list可變對象引用
- b = a #b跟a指向同一個對象引用
- a[0] = 2 #改變a對象引用的值,那麼跟a指向同一個對象引用的b的值也隨之同步改變。
- print a,b #結果是2,2
- def func(a):
- a[0]=1 #改變a對象引用的值,那麼跟a指向同一個對象引用的b的值也隨之同步改變。
- b=['2']
- func(b) #上面提到,函數的參數傳遞就是傳對象引用,所以這裏就相當於b=a,即b跟a指向同一個對象引用
- print b #結果[1]
注意下面這個例子跟上面例子的區別。
- def func(a):
- a=['1'] #這裏並沒有修改a指向的對象引用的值,而是a指向了新的對象引用,所以最後b的值沒有改變。
- b=['2']
- func(b)
- print b #結果[2]