轉自: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異常。