Python中的引用和拷貝淺析

來源:互聯網
上載者:User
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個引用了呢?誰知道?
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.