赋值、深拷贝、浅拷贝
1.概述
python跟java中的变量本质是不一样的,Python的变量实质上是一个指针(int型或str型),而java的变量是一个可操作的存储空间。
(1)不可变对象
a = 1 b = a print(id(a), id(b)) a = 2 #不可变对象被重新赋值,重新分配了一块内存,ID就变了 print(a, b) print(id(a), id(b))
运行结果:
(2) 列表直接赋值给列表不属于拷贝, 只是内存地址的引用
list1 = ["a", "b", "c"] list2 = list1 list1.append("d") print(list1, list2) print(id(list1), id(list2))
运行结果:
2.赋值(=)、深拷贝、浅拷贝
- =: 跟原对象完全相同,原对象改了啥,新对象也改了啥;
- deepcopy: 原对象改了啥,新对象都不变
- copy: 列表的列表会被修改
copy浅拷贝:拷贝一个对象,但是对象的属性还是引用原来的,对于可变类型,比如列表和字典,只是复制其引用。基于引用所作的改变会影响到被引用对象。只要原来的对象改变,被浅拷贝的就会改变。
deepcopy深拷贝:创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用。外围和内部元素都是拷贝对象本身,而不是引用。原来的对象改变了,不会影响到新的深拷贝的。
注意:对于数字,字符串和其他原子类型等,没有被拷贝的说法。如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。使用copy和deepcopy时,需要了解其使用场景,避免错误。
运行结果:
# 浅拷贝 list1 = ["a", "b", "c"] list2 = list1.copy() list3=list(list1) #转换也是浅copy list1.append("d") print(list1, list2,list3) print(id(list1), id(list2),id(list3))
运行结果:
浅拷贝, 只会拷贝第一层, 第二层的内容不会拷贝
运行结果:
# 浅拷贝, 只会拷贝第一层, 第二层的内容不会拷贝 list1 = ["a", "b", "c", [1, 2, 3]] list2 = list1.copy() list1[3].append(4) print(list1, list2) print(id(list1), id(list2))