指的是内存区域可变和不可变
可变:字典、列表
不可变:数字、字符串、元组
浅复制:引用复制,并没有产生新的地址
如果拷贝对象,原对象和copy对象都指向一个内存空间,只拷贝父对象,不会拷贝对象的内部子对象
用法:copy.copy(变量)
深拷贝:会产生新的空间
如果拷贝对象和原对象不是指向一个内存空间,会拷贝父对象与子对象
用法:copy.deecopy(变量)
可变类型:浅拷贝也会产生新的内存空间,能够保持对立性
可变类型:深拷贝会产生新的内心空间,能够保持独立性
# 可变: 变量创建完成后,内存可以改变
# 列表和字典
import copy
def test():
# 可变类型的 浅拷贝 也会产生新的空间,能够保持各自的独立性
list1 = [1, 2, 3]
print("list1 = ", list1, id(list1))
# list3 = list1
# list3.append(5)
# print("list3 = ",list3,id(list3))
# 拷贝:
# 1、导入模块 copy
# 2、调用方法
# copy(变量) 产生副本,浅拷贝
list2 = copy.copy(list1)
print("list2 = ", list2, id(list2))
# 修改list1
list1.append(5)
print("list1 = ", list1, id(list1))
print("list2 = ", list2, id(list2))
list1 = [1, 2, 3]
print("list1 = ", list1, id(list1))
# deepcopy(变量) 产生副本,深拷贝
list2 = copy.deepcopy(list1)
print("list2 = ", list2, id(list2))
# 修改list2
list2.append(7)
print("list2 = ", list2, id(list2))
print("list1 = ", list1, id(list1))
# 总结:简单可变类型的深拷贝,会产生新的空间,能够保持的各自的独立性
复杂可变类型拷贝
浅拷贝:拷贝父对象,子对象不会拷贝
深拷贝:拷贝父对象,子对象会拷贝
import copy
def test():
A = [1, 2, 3]
B = [11, 22, 33]
# [[1, 2, 3], [11, 22, 33]]
C = [A, B]
print("A = ", A, id(A))
print("B = ", B, id(B))
print("C = ", C, id(C))
print("C[0] = ", C[0], id(C[0]))
# 对复杂可变类型进行浅拷贝
# D产生了新的空间
D = copy.copy(C)
print("D = ", D, id(D))
print("D[0] = ", D[0], id(D[0]))
# 修改A的
A[0] = 10
print("A = ", A, id(A))
print("D[0] = ", D[0], id(D[0]))
A = [1, 2, 3]
B = [11, 22, 33]
# [[1, 2, 3], [11, 22, 33]]
C = [A, B]
print("A = ", A, id(A))
print("C = ", C, id(C))
# print("C[0] = ", C[0], id(C[0]))
# 对C做深拷贝
D = copy.deepcopy(C)
print("D = ", D, id(D))
print("D[0]=",id(D[0]),"C[0]=",id(C[0]),"A=",id(A))
A[0] = 10
print("A = ", A, id(A))
print("D[0] = ", D[0], id(D[0]))
简单不可变类型拷贝
浅拷贝等价于“=”
结论:深浅拷贝,副本有源指向同一个内存空间
import copy
def test_copy():
# 简单不可变的元组
tuple1 = (1, 2, 3)
print("tuple1 = ", tuple1, id(tuple1))
# 对简单不可变类型做浅拷贝
# 等价于 tuple2 = tuple1
tuple2 = copy.copy(tuple1)
print("tuple2 = ", tuple2, id(tuple2))
# 简单不可变的元组
tuple1 = (1, 2, 3)
print("tuple1 = ", tuple1, id(tuple1))
# 等价于 tuple2 = tuple1
tuple2 = copy.deepcopy(tuple1)
print("tuple2 = ", tuple2, id(tuple2))
复杂不可变类型拷贝
浅拷贝:直接引用
深拷贝:看数据具体是可变还是不可变的,如果数据是可变的,会产生新的空间,保持数据的独立性
def test_copy():
A = [1, 2, 3]
B = [11, 22, 33]
# 定义元组
C = (A, B)
print("C = ", C, id(C))
# C[0] = [100,200,300]
# 复杂不可变类型的浅拷贝
# D = C
D = copy.copy(C)
print("D = ", D, id(D))
print("D[0]", id(D[0]), "C[0]", id(C[0]), "A", id(A))
D[0][0] = 10 # D[0]==C[0]
print("D = ", D, id(D))
A = [1, 2, 3]
B = [11, 22, 33]
# 定义元组
C = (A, B)
print("C = ", C, id(C))
# 对C做深拷贝
D = copy.deepcopy(C)
print("D = ", D, id(D))
print("D[0]", id(D[0]), "C[0]", id(C[0]), "A", id(A))
# D拷贝自C,也是不可变的,D[0] 是一个列表,是可变的,通过D[0][0] 修改值
# D[0] = [100,200,300]
D[0][0] = 10
print("D = ", D, id(D))
print("C = ", C, id(C))
切片拷贝与字典拷贝
- 切片拷贝: 浅拷贝(如果是简单可变类型,底层会产生新的空间)
- 字典拷贝: 浅拷贝
def test():
# 0 1 2 3 4 5 6
# 简单、可变 深拷贝
list1 = [1, 2, 3, 4, 5, 6, 7]
print("list1 = ", list1, id(list1))
# 切片拷贝,地址不一样
list2 = list1[:]
print("list2 = ", list2, id(list2))
def test_2():
A = [1,2,3]
B = [11,22,33]
C = (A,B)
print("C = ",C,id(C))
D = C[:]
print("D = ",D,id(D))
dict1 = {"age":[1,2]}
print("dict1 = ",dict1, id(dict1))
dict2 = dict1.copy()
print("dict2 = ",dict2, id(dict2))
print("--"*20)
dict1['age'][0] = 100
print("dict1 = ",dict1, id(dict1))
print("dict2 = ",dict2, id(dict2))



