python中的copy模塊(淺複製和深複製)

轉自:http://blog.csdn.net/wyabc1986/article/details/7731395


主要是介紹python中的copy模塊。


copy模塊包括創建複合對象(包括列表、元組、字典和用戶定義對象的實例)的深淺複製的函數。



########

copy(x)

########

創建新的複合對象並通過引用複製x的成員來創建x的淺複製。更加深層次說,

它複製了對象,但對於對象中的元素,依然使用引用。

對於內置類型,此函數並不經常使用。

而是使用諸如list(x), dict(x), set(x)等調用方式來創建x的淺複製,要知道像這樣

直接使用類型名顯然比使用copy()快很多。但是它們達到的效果是一樣的。

還有一點就是對於那些不可修改的對象(string, 數字, 元組),因爲你不用擔心修改他們。複製不復制也就沒有

什麼大的意義了。

另外一點,你判斷對象之間是否是拷貝,可以使用is運算符來確定。

a is b -> True  a與b引用的是同一個對象,不是拷貝

       -> False a與b是彼此拷貝對象

       

例如下面的例子,eg:

(1)

>>> a = [1,2,3]

>>> b = copy.copy(a)

>>> b

[1, 2, 3]

>>> a.append(4)

>>> a

[1, 2, 3, 4]

>>> b

[1, 2, 3]

>>> a is b

False


(2)

>>> a = [1,2,3]

>>> b = a

>>> b

[1, 2, 3]

>>> a.append(4)

>>> a

[1, 2, 3, 4]

>>> b

[1, 2, 3, 4]

>>> b.append(6)

>>> a, b

([1, 2, 3, 4, 6], [1, 2, 3, 4, 6])


(3)

>>> a = [1,2,3]

>>> b = list(a)

>>> b

[1, 2, 3]

>>> a.append(4)

>>> a

[1, 2, 3, 4]

>>> b

[1, 2, 3]

>>> 


(4)

>>> a = [[1], ['a'], ['A']]

>>> b = copy.copy(a)

>>> print a, b

[[1], ['a'], ['A']] [[1], ['a'], ['A']]

>>> b[1].append('b')

>>> b

[[1], ['a', 'b'], ['A']]

>>> a

[[1], ['a', 'b'], ['A']]

>>> b.append([100,101])

>>> b

[[1], ['a', 'b'], ['A'], [100, 101]]

>>> a

[[1], ['a', 'b'], ['A']]

在(3)例子當中,我們可以看到a的淺複製對象b,它們是不同的對象,所以對對象的改變是不會

影響彼此的,但是這些a和b對象的元素是引用的同一個,所以a或者b更改了它的對象的元素就會影響到

另外一個的值。

如果你想完全的拷貝一個對象和一個對象的所有元素的值,只有使用下面的deepcopy()函數。



#######################

deepcopy(x[, visit])

#######################

通過創建新的複合對象並重複復制x的所有成員來創建x的深複製。

visit是一個可選的字典,目的是跟蹤受訪問的對象,從而檢測和避免重複定義

的數據結構中的循環。


儘管通常情況下不需要,但是通過實現方法__copy__(self)和__deepcopy__(self, visit),

類就可以實現自定義的複製方法,這兩個方法分別實現了淺複製和深複製操作。

__deepcopy__()方法必須使用字典visit,用來在複製過程中跟蹤前面遇到的對象。對於

__deepcopy__()方法,除了將visit傳到實現中包含的其他deepcopy()方法(如果有的話)之外,

沒有必要在執行其他操作。


如果類實現了pickle模塊所用的方法__getstate__()和__setstate__(),那麼copy模塊將使用

這些方法來創建副本。

,但是通過實現方法__copy__(self)和__deepcopy__(self, visit),

類就可以實現自定義的複製方法,這兩個方法分別實現了淺複製和深複製操作。

__deepcopy__()方法必須使用字典visit,用來在複製過程中跟蹤前面遇到的對象。對於

__deepcopy__()方法,除了將visit傳到實現中包含的其他deepcopy()方法(如果有的話)之外,

沒有必要在執行其他操作。


如果類實現了pickle模塊所用的方法__getstate__()和__setstate__(),那麼copy模塊將使用

這些方法來創建副本。,但是通過實現方法__copy__(self)和__deepcopy__(self, visit),

類就可以實現自定義的複製方法,這兩個方法分別實現了淺複製和深複製操作。

__deepcopy__()方法必須使用字典visit,用來在複製過程中跟蹤前面遇到的對象。對於

__deepcopy__()方法,除了將visit傳到實現中包含的其他deepcopy()方法(如果有的話)之外,

沒有必要在執行其他操作。


如果類實現了pickle模塊所用的方法__getstate__()和__setstate__(),那麼copy模塊將使用

這些方法來創建副本。

eg:

>>> a = [[1], ['a'], ['A']]

>>> import copy

>>> b = copy.deepcopy(a)

>>> b

[[1], ['a'], ['A']]

>>> c = copy.copy(a)

>>> c

[[1], ['a'], ['A']]

>>> a[1].append('b')

>>> a

[[1], ['a', 'b'], ['A']]

>>> b

[[1], ['a'], ['A']]

>>> c

[[1], ['a', 'b'], ['A']]



需要注意的是:

(1)  copy模塊用於像整數和字符串這樣的簡單類型,不過很少需要這麼做。

(2)   這些複製函數無法與模塊、類對象、函數、方法、回溯、棧幀、文件、套接字和其他類似類型同時工作。

如果不能複製對象,則會引發copy.error異常。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章