浅谈浅拷贝与深拷贝
浅拷贝
一 、不可变类型(字符串、数字、元组)
copy函数是浅拷贝,只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象。
import copy
# 不可变类型: 数字 、字符串、 元组
a1 = "abc"
b1 = copy.copy(a1)
# 查看内存地址
print(a1, id(a1))
print(b1, id(b1))
# 内存地址相同 abc 2189271452784
print("=" * 30)
a2 = 123
b2 = copy.copy(a2)
# 查看内存地址
print(a2, id(a2))
print(b2, id(b2))
# 内存地址相同 123 1823767392
print("=" * 30)
a3 = (123, "abc", [1, 2])
b3 = copy.copy(a3)
# 查看内存地址
print(a3, id(a3))
print(b3, id(b3))
# 内存地址相同 2234778896712
print("=" * 30)
# 查看子对象内存地址
print(a3[1], id(a3[1]))
print(b3[1], id(b3[1]))
# 内存地址相同 abc 2923810278512
print("="*30)
print(a3[2], id(a3[2]))
print(b3[2], id(b3[2]))
# 内存地址相同 [1, 2] 3120014823816
运行结果为:
"C:\Program Files\Python36\python.exe" D:/黑马程序员/就业班/project/tcp客户端/static/14-demo.py
abc 3120012414064
abc 3120012414064
==============================
123 1823767392
123 1823767392
==============================
(123, 'abc', [1, 2]) 3120013306976
(123, 'abc', [1, 2]) 3120013306976
==============================
abc 3120012414064
abc 3120012414064
==============================
[1, 2] 3120014823816
[1, 2] 3120014823816
Process finished with exit code 0
总结:
copy函数的浅拷贝,不能对不可变类型的第一层对象进行拷贝,所以并不能对其开辟新的内存空间,拷贝的只是该第一层对象的引用,对于该类型的子对象(任意类型)都不能对其进行拷贝,
import copy
# 可变类型有 列表、字典、集合
a1 = [1, 2, [3, 4]]
b1 = copy.copy(a1)
# 查看内存地址
print(a1, id(a1))
print(b1, id(b1))
# 查看a1[0]的内存地址
print(a1[0], id(a1[0]))
print(a1[0], id(a1[0]))
# 查看a1[2]的内存地址
print(a1[2], id(a1[2]))
print(a1[2], id(a1[2]))
# 浅拷贝只能对可变类型的第一层对象进行拷贝,开辟新的内存空间,对其子对象不会进行拷贝,不开辟新的内存空间
print("=" * 30)
a2 = {"name": "王五", "age": 20}
b2 = copy.copy(a2)
# 查看内存地址
print(a2, id(a2))
print(b2, id(b2))
# 内存地址改变
print("=" * 30)
a3 = {2, "王五", 9}
b3 = copy.copy(a3)
# 查看内存地址
print(a3, id(a3))
print(b3, id(b3))
# 内存地址改变
运行结果为:
[1, 2, [3, 4]] 1651987190408
[1, 2, [3, 4]] 1651987191688
1 1823763488
1 1823763488
[3, 4] 1651987190216
[3, 4] 1651987190216
==============================
{'name': '王五', 'age': 20} 1651984857992
{'name': '王五', 'age': 20} 1651984858064
==============================
{'王五', 9, 2} 1651985048296
{'王五', 9, 2} 1651987207784
Process finished with exit code 0
**
- 通过上面的执行结果可以得知,可变类型进行浅拷贝只对可变类型的第一层对象进行拷贝,对拷贝的对象会开辟新的内存空间进行存储,子对象不进行拷贝。
**
深拷贝
- 不可变类型:
import copy
# 不可变类型 元组,数字,字符串
a1 = 1
b1 = copy.deepcopy(a1)
# 查看内存地址
print(a1, id(a1))
print(b1, id(b1))
# 地址未改变 1 1823763488
print("=" * 30)
a2 = "abc"
b2 = copy.deepcopy(a2)
# 查看内存地址
print(a2, id(a2))
print(b2, id(b2))
# 地址未改变 abc 1653192608880
print("=" * 30)
a3 = ("a", 2,)
b3 = copy.deepcopy(a3)
# 查看内存地址
print(a3, id(a3))
print(b3, id(b3))
# 地址未改变 ('a', 2) 1996651219528
print("=" * 30)
a4 = ("a", 2, [1, 2])
b4 = copy.deepcopy(a4)
# 查看内存地址
print(a4, id(a4))
print(b4, id(b4))
# 地址改变
# ('a', 2) 1773520284768
# ('a', 2) 1773521873296
print("=" * 30)
print(a4[0], id(a4[0]))
print(b4[0], id(b4[0]))
# 地址未改变 a 1870970679056
print("=" * 30)
print(a4[2], id(a4[2]))
print(b4[2], id(b4[2]))
# 地址改变
# [1, 2] 1951827038664
# [1, 2] 1951827040136
**
**
**
由此可知,当不可变类型的子对象有可变类型时,该对象便可以被拷贝,并会为其开辟新的内存空间
其子对象若是可变类型,则会被拷贝,开辟新内训空间,若子对象为不可变类型,则不会不被拷贝, 拷贝的只是他的引用
**
运行结果为:
1 1823763488
1 1823763488
==============================
abc 1951824628848
abc 1951824628848
==============================
('a', 2) 1951825578696
('a', 2) 1951825578696
==============================
('a', 2, [1, 2]) 1951825521760
('a', 2, [1, 2]) 1951827110216
==============================
a 1951824539408
a 1951824539408
==============================
[1, 2] 1951827038664
[1, 2] 1951827040136
Process finished with exit code 0
- 可变类型
-`import copy # 使用深拷贝需要导入copy模块
可变类型有: 列表、字典、集合
a1 = [1, 2]
b1 = copy.deepcopy(a1) # 使用copy模块里的deepcopy()函数就是深拷贝了
#查看内存地址
print(id(a1))
print(id(b1))
内存地址改变 1935350763912 1935350764104
print("-" * 10)
a2 = {"name": "张三"}
b2 = copy.deepcopy(a2)
查看内存地址
print(id(a2))
print(id(b2))
内存地址改变 1474406742920 1474436687480
print("-" * 10)
a3 = {1, 2}
b3 = copy.deepcopy(a3)
查看内存地址
print(id(a3))
print(id(b3))
内存地址改变 1891791758056 1891793917544
print("-" * 10)
a4 = [1, 2, ["李四", "王五"]]
b4 = copy.deepcopy(a4) # 使用copy模块里的deepcopy()函数就是深拷贝了
#查看内存地址
print(id(a4))
print(id(b4))
#内存地址改变
#查看内存地址
print(id(a4[2]))
print(id(b4[2]))
#内存地址改变 2678386661384 2678386661192
print(id(a4[0]))
print(id(b4[0]))
#内存地址未改变 1823763488
由此可知,深拷贝可以对可变类型的对象进行深层拷贝,当子对象为可变类型时,拷贝并开辟新的内存空间,
#子对象若为不可变类型时,同样不会为其开辟新的内存空间,只是拷贝了他的引用
来源:CSDN
作者:?Mr.Liu??17530174296
链接:https://blog.csdn.net/lzn1210899799/article/details/103788204