直接赋值:其实就是对象的引用(别名)。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
实例:
import copy
a = ["a", ["b", "c"]]
b = a
d = copy.deepcopy(a)
c = copy.copy(a)
a.append("d")
a[1].append("e")
print(a, b, c, d)
输出内容:
['a', ['b', 'c', 'e'], 'd'] ['a', ['b', 'c', 'e'], 'd'] ['a', ['b', 'c', 'e']] ['a', ['b', 'c']]
- 使用copy时,c只复制了a的父对象,a和c的子对象仍指向同一对象,所以
a[1].append("e")
a的子对象发生修改时,c也改变了,但是a.append("d")
并未改变c,因为a,c的父对象相互独立。 - 使用deepcopy时,a与d的子对象,父对象都相互独立,所以当a发生改变时,d未发生改变。
其他例子
实例1:
import copy
a = ["a", "b", "c"]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
print(a, b, c, d)
print(id(a), id(b), id(c), id(d))
输出内容:
['a', 'b', 'c'] ['a', 'b', 'c'] ['a', 'b', 'c'] ['a', 'b', 'c']
1952786892928 1952786892928 1952786869760 1952786944768
实例2:
import copy
a = ("a", "b", "c")
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
print(a, b, c, d)
print(id(a), id(b), id(c), id(d))
输出内容:
('a', 'b', 'c') ('a', 'b', 'c') ('a', 'b', 'c') ('a', 'b', 'c')
1436892318272 1436892318272 1436892318272 1436892318272
实例3:
import copy
a = ("a", ["b", "c"])
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
print(a, b, c, d)
print(id(a), id(b), id(c), id(d))
输出内容:
('a', ['b', 'c']) ('a', ['b', 'c']) ('a', ['b', 'c']) ('a', ['b', 'c'])
2377116479296 2377116479296 2377116479296 2377116506368
- 在以上三个实例中,使用直接赋值的a,b一直指向同一对象。因为直接赋值时,相当与给a创建了一个别名。
- 在实例1中,c和d的内存地址都发生了变化,因为copy和deepcopy会拷贝父对象,此时a与c,a与d都是相互独立的,所以内存地址发生了变化。
- 在实例2中,因为a元组是不可变对象,使用copy和deepcopy不会改变内存地址,所以a与c,a与d是一样的。
- 在实例3中,a的元组内包含一个可变子对象-列表,因为copy只拷贝父对象。a的父对象是元组,所以a和c的内存地址未变化。使用deepcopy时,会完全拷贝父对象与子对象,所以a和d的地址不一样。