If an object's value can be modified, the object is said to be mutable. If the value cannot be modified,the object is said to be immutable.
mutable 可變類型,例如 list,set,自定義類型(等價于C#中的引用類型);
immutable 不可變類型,例如string,numbers等(等價于C#中的值類型);
一、引用和拷貝(references and copies)
當程序中使用=賦值操作符時,例如a=b,
對于不可變的對象,a作為b的一個拷貝被創建,a和b將指向不同的內存地址,a和b相互獨立。
def TestCopy():
??? a = 10
??? b = a
??? a =20
??? print (b) #b still is 10
但是對于可變的對象,a作為b的一個引用被創建,a和b的元素公用相同的內存地址,a和b的元素共享。
def TestRef():
??? a=[1,2,3,4]
??? b=a?? #b is a reference to a
??? print (b is a) # True
??? b[2] = -100 #change an element in b
??? print (a) # a also changed to [1,2,-100,4]
二、深拷貝和淺拷貝(shallow copy and deep copy)
為了避免可變對象指向同一個對象,必須創建一個新的拷貝,而不是引用。
在python中可以對容器對象(例如lists和dictionaries)使用兩種拷貝:淺拷貝和深拷貝。
?
淺拷貝創建一個新的對象,但是使用原來對象的元素的引用(如果是不變類型,相當于是拷貝)來填充新對象。可以使用copy.copy()來實現淺拷貝。
def TestShallowCopy():
??? a = [ 1, 2, [3,4] ]
??? b = list(a) # create a shallow copy of a
??? print (b is a) #False
??? b.append(100) #append element to b
??? print (b)
??? print (a) # a is unchanged
??? b[2][0] = -100 # modify an element inside b
??? print (b)
??? print (a)? # a is changed
在這個例子中,a和b共享相同的可變元素。所以修改其中一個list對象中的元素,另一個list對象也會被修改。
深拷貝創建一個新的對象,同時遞歸地拷貝對象所包含的所有的元素。可以使用copy.deepcopy()來實現深拷貝。
def TestDeepCopy():
? import copy
? a = [1, 2, [3, 4]]
? b = copy.deepcopy(a)
? b[2][0] = -100
? print (b)? # b is changed
? print (a)? # a is unchanged
在這個例子中,a和b是對立的list對象,且他們的元素也相互獨立。
三、引用計數和垃圾回收
python中的所有的對象都是引用計數的,一個對象賦值或加入容器時,它的引用計數就會自增,當使用del時或變量賦值為其他值時,引用計數就會自減,當引用計數為0時,python的垃圾回收器就會回收該變量。
def TestGarbageCollection():
? import sys
? print(sys.getrefcount(37))
? a = 37 # Creates an object with value 37
? print(sys.getrefcount(37))
? b = a # Increases reference count on 37
? print(sys.getrefcount(37))
? c = []
? c.append(b) # Increases reference count on 37
? print(sys.getrefcount(37))
? del a # Decrease reference count of 37
? print(sys.getrefcount(37))
? b = 42 # Decrease reference count of 37
? print(sys.getrefcount(37))
? c[0] = 2.0 # Decrease reference count of 37
? print(sys.getrefcount(37))
?
TestGarbageCollection()
運行結果為:
11
12
13
14
13
12
11
為啥一上來就有11個引用了呢?誰知道?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
