Python赋值、浅拷贝与深拷贝的核心区别解析
本文深入解析Python中赋值、浅拷贝与深拷贝的区别。赋值仅复制引用,共享内存;浅拷贝创建新对象但内部元素仍引用原对象;深拷贝则完全独立,不共享任何嵌套对象。通过不可变与可变对象的代码示例,清晰展示三者在不同场景下的行为差异。
一、赋值
赋值操作不会开辟新的内存空间,仅仅是复制了新对象在内存中的引用地址。因此,当其中一个变量指向的数据发生变化时,另一个变量也会随之改变,因为它们指向的是同一个对象。
二、浅拷贝
浅拷贝会创建一个新的对象,但其内容是对原对象内部元素的引用。之所以称为“浅”拷贝,是因为它只处理了第一层结构,即只拷贝了最外层的对象本身。内部元素(如列表中的子列表或字典中的子字典)仅仅拷贝了它们的引用。这意味着,如果内部元素被修改,原对象和浅拷贝后的对象都会受到影响。
在Python中,实现浅拷贝主要有以下三种方式:
A = [1, 2, 3, 4]
- 切片操作
# 第1种
B = A[:]
# 第2种
B = [a for a in A]
- 工厂函数
B = list(A)
- copy模块中的copy函数
B = copy.copy(A)
浅拷贝的行为需要根据被拷贝对象的类型分为两种情况进行讨论:
1)当浅拷贝的值是不可变对象(例如字符串、元组、数值类型)时,其行为与赋值类似。此时,原对象与浅拷贝后的对象内存地址(id())一致,因为它们指向同一个不可变对象。
2)当浅拷贝的值是可变对象(例如列表、字典、集合等)时,需要进一步分两种情况讨论:
首先,原对象与浅拷贝后的对象,其最外层的内存地址是不同的,说明它们是两个独立的容器对象。
- 当要拷贝的对象内部不包含可变子对象时,修改原对象(或拷贝对象)的外层内容,不会影响另一个对象。
- 当要拷贝的对象内部包含可变子对象时,如果修改该子对象的内容,原对象和浅拷贝后的对象都会反映出这一变化,因为它们共享子对象的引用。
三、深拷贝
深拷贝会递归地创建一个新的对象,这个新对象与原对象在内存中完全独立,没有任何关联。无论原对象如何修改,包括其内部嵌套的可变对象,都不会影响深拷贝出来的新对象。
四、例子
- 不可变对象
import copy
# 不可变对象
# A = (1, 2, 'hello') # 元组
# A = 1 # 数值
A = 'hello' # 字符串
print("********赋值********")
B = A
print(id(A))
print(id(B))
print(A)
print(B)
print("********浅拷贝********")
B = copy.copy(A)
print(id(A))
print(id(B))
print(A)
print(B)
print("********深拷贝********")
B = copy.deepcopy(A)
print(id(A))
print(id(B))
print(A)
print(B)
结果:
********赋值******** 1894005658264 1894005658264 hello hello ********浅拷贝******** 1894005658264 1894005658264 hello hello ********深拷贝******** 1894005658264 1894005658264 hello hello
- 可变对象
import copy
# 可变对象
A = [1, 2, 3]
print("********赋值********")
B = A
print(id(A))
print(id(B))
print(A)
print(B)
print("********浅拷贝********")
B = copy.copy(A)
print(id(A))
print(id(B))
print(A)
print(B)
print("********深拷贝********")
B = copy.deepcopy(A)
print(id(A))
print(id(B))
print(A)
print(B)
结果:
********赋值******** 1602694308360 1602694308360 [1, 2, 3] [1, 2, 3] ********浅拷贝******** 1602694308360 1602694308424 [1, 2, 3] [1, 2, 3] ********深拷贝******** 1602694308360 1602950316296 [1, 2, 3] [1, 2, 3]
- 可变对象修改外层
import copy
# 可变对象
A = [1, 2, 3, [11, 10, 20]]
# 可变对象的外层修改
B1 = A # 赋值
B2 = copy.copy(A) # 浅拷贝
B3 = copy.deepcopy(A) # 深拷贝
A.append(4)
print("********赋值********")
print(id(A))
print(id(B1))
print(A)
print(B1)
print("********浅拷贝********")
print(id(A))
print(id(B2))
print(A)
print(B2)
print("********深拷贝********")
print(id(A))
print(id(B3))
print(A)
print(B3)
结果:
********赋值******** 2215309238856 2215309238856 [1, 2, 3, [11, 10, 20], 4] [1, 2, 3, [11, 10, 20], 4] ********浅拷贝******** 2215309238856 2215593496776 [1, 2, 3, [11, 10, 20], 4] [1, 2, 3, [11, 10, 20]] ********深拷贝******** 2215309238856 2215593518024 [1, 2, 3, [11, 10, 20], 4] [1, 2, 3, [11, 10, 20]]
- 可变对象修改内层
import copy
# 可变对象
A = [1, 2, 3, [11, 10, 20]]
# 可变对象的内层修改
B1 = A # 赋值
B2 = copy.copy(A) # 浅拷贝
B3 = copy.deepcopy(A) # 深拷贝
A[3].append(4)
print("********赋值********")
print(id(A))
print(id(B1))
print(A)
print(B1)
print("********浅拷贝********")
print(id(A))
print(id(B2))
print(A)
print(B2)
print("********深拷贝********")
print(id(A))
print(id(B3))
print(A)
print(B3)
结果
********赋值******** 2288591069768 2288591069768 [1, 2, 3, [11, 10, 20, 4]] [1, 2, 3, [11, 10, 20, 4]] ********浅拷贝******** 2288591069768 2288847138760 [1, 2, 3, [11, 10, 20, 4]] [1, 2, 3, [11, 10, 20, 4]] ********深拷贝******** 2288591069768 2288847168264 [1, 2, 3, [11, 10, 20, 4]] [1, 2, 3, [11, 10, 20]]
到此这篇关于Python基础之赋值,浅拷贝,深拷贝的区别的文章就介绍到这了,更多相关Python赋值 浅拷贝 深拷贝的区别内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









