Python中的引用和拷貝淺析
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)
當(dāng)程序中使用=賦值操作符時,例如a=b,
對于不可變的對象,a作為b的一個拷貝被創(chuàng)建,a和b將指向不同的內(nèi)存地址,a和b相互獨立。
def TestCopy():
a = 10
b = a
a =20
print (b) #b still is 10
但是對于可變的對象,a作為b的一個引用被創(chuàng)建,a和b的元素公用相同的內(nèi)存地址,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)
為了避免可變對象指向同一個對象,必須創(chuàng)建一個新的拷貝,而不是引用。
在python中可以對容器對象(例如lists和dictionaries)使用兩種拷貝:淺拷貝和深拷貝。
淺拷貝創(chuàng)建一個新的對象,但是使用原來對象的元素的引用(如果是不變類型,相當(dāng)于是拷貝)來填充新對象??梢允褂胏opy.copy()來實現(xiàn)淺拷貝。
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對象也會被修改。
深拷貝創(chuàng)建一個新的對象,同時遞歸地拷貝對象所包含的所有的元素??梢允褂胏opy.deepcopy()來實現(xiàn)深拷貝。
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對象,且他們的元素也相互獨立。
三、引用計數(shù)和垃圾回收
python中的所有的對象都是引用計數(shù)的,一個對象賦值或加入容器時,它的引用計數(shù)就會自增,當(dāng)使用del時或變量賦值為其他值時,引用計數(shù)就會自減,當(dāng)引用計數(shù)為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()
運行結(jié)果為:
11
12
13
14
13
12
11
為啥一上來就有11個引用了呢?誰知道?
相關(guān)文章
使用Python將xmind腦圖轉(zhuǎn)成excel用例的實現(xiàn)代碼(一)
這篇文章主要介紹了使用Python將xmind腦圖轉(zhuǎn)成excel用例的實現(xiàn)代碼(一),本文給大家介紹的非常詳細(xì)對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Python?NumPy教程之?dāng)?shù)組的創(chuàng)建詳解
這篇文章主要為大家詳細(xì)介紹了Python?NumPy中數(shù)組的創(chuàng)建方式,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-08-08PyTorch的Optimizer訓(xùn)練工具的實現(xiàn)
這篇文章主要介紹了PyTorch的Optimizer訓(xùn)練工具的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08詳解用Python進(jìn)行時間序列預(yù)測的7種方法
這篇文章主要介紹了詳解用Python進(jìn)行時間序列預(yù)測的7種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03python調(diào)用百度REST API實現(xiàn)語音識別
這篇文章主要為大家詳細(xì)介紹了python調(diào)用百度REST API實現(xiàn)語音識別,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08