98.对象的浅拷贝和深拷贝
- 变量的赋值操作
只是形成两个变量
,实际还是指向同一个对象
。
浅拷贝
 Python拷贝一般都是浅拷贝
。拷贝时,对象包含的子对象
内容不拷贝
。因此,源对象 和拷贝对象
会引用同一个子对象
。
深拷贝
使用copy
模块的 deepcopy
函数,递归拷贝对象中包含的子对象
。源对象和拷贝对象 所有的子对象也不同。
测试对象的浅拷贝和深拷贝
class MobilePhone:
def __init__(self, cpu, screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self): # 这个单词是 计算的意思
print("算你个12345")
print("cpu对象:", self)
class Screen:
def show(self):
print("显示一个好看的画面,亮瞎你的钛合金大眼")
print("screen对象:", self)
# 测试变量赋值
import copy
c1 = CPU()
c2 = c1
print(c1)
print(c2)
print("测试浅复制....")
# 测试浅复制
In [2]: c1 = CPU()
...: c2 = c1
In [3]:
In [3]:
In [3]: c1
Out[3]: <__main__.CPU at 0x59313d0>
In [4]: c2
Out[4]: <__main__.CPU at 0x59313d0>
In [6]: # c1 和 c2 是两个不同的对象
In [7]: # 开始测试浅拷贝
In [8]: s1 = Screen()
...: m1 = MobilePhone(c1, s1)
...: m2 = copy.copy(m1)
In [9]: s1
Out[9]: <__main__.Screen at 0x5ffb850>
In [11]: m1
Out[11]: <__main__.MobilePhone at 0x5ffb6b0>
In [12]: m2
Out[12]: <__main__.MobilePhone at 0x5ffb3b0>
# 可以看到 m1 和 m2 是不一样的 对象。
# 这里就可以理解为 两个手机 但是 用的屏幕 和 CPU 却是 同一个 东西。
# 说明 你这个 就是 外面 套了 个 壳子 呗。
# 只是说 现实世界不会 同时出现 套壳 的手机 和 原来 的手机 同时 出现。
# 但是计算机 里面 就可以可以。 因为 里面装的 只是 一个 引用地址。 指向的同样的地方。
# 以下 是证明
In [13]: print(f"mobilephone -> {m1} | 'cpu' -> {m1.cpu} |'screen' ->
...: {m1.screen}")
mobilephone -> <__main__.MobilePhone object at 0x05FFB6B0> | 'cpu' -> <__main__.CPU object at 0x059313D0> |'screen' -> <__main__.Screen object at 0x05FFB850>
In [14]: print(f"mobilephone -> {m2} | 'cpu' -> {m2.cpu} |'screen' -> {m2.screen}")
mobilephone -> <__main__.MobilePhone object at 0x05FFB3B0> | 'cpu' -> <__main__.CPU object at 0x059313D0> |'screen' -> <__main__.Screen object at 0x05FFB850>
# 测试深复制
print("测试深复制....")
m3 = copy.deepcopy(m1)
print(m1, m1.cpu, m1.screen)
print(m3, m3.cpu, m3.screen)
# 这次可以看到 不但 手机不一样。 cpu 和 屏幕 也是不一样的 对象。
# 这就是 深拷贝
In [15]: m3 = copy.deepcopy(m1)
...: print(m1, m1.cpu, m1.screen)
...: print(m3, m3.cpu, m3.screen)
<__main__.MobilePhone object at 0x05FFB6B0> <__main__.CPU object at 0x059313D0> <__main__.Screen object at 0x05FFB850>
<__main__.MobilePhone object at 0x012505F0> <__main__.CPU object at 0x01250CB0> <__main__.Screen object at 0x0126FE50>