Python中直接赋值、浅拷贝和深拷贝的区别

1 Python中直接赋值、浅拷贝和深拷贝的概念

直接赋值: 创建一个别名,本质上是对象引用。
浅拷贝: 拷贝父对象,而不会拷贝父对象内部的子对象。操作上,重新分配一块内存用于创建父对象,内部包含子对象的引用。
深拷贝: 完全拷贝父对象和子对象。新对象与原对象不再有关系。

在这里插入图片描述

2 浅拷贝和深拷贝在内存地址上的区别

此处引用 时代&信念 的博文内容。

浅拷贝:

父对象数据类型子对象数据类型父对象地址子对象地址
可变可变改变相同
可变不可变改变相同
不可变可变相同相同
不可变不可变相同相同

结论: 使用浅拷贝时,子对象相同;如果父对象为可变数据类型,则父对象不同,如果父对象为不可变数据类型,则父对象相同。

深拷贝:

父对象数据类型子对象数据类型父对象地址子对象地址
可变可变改变改变
可变不可变改变相同
不可变可变改变改变
不可变不可变相同相同

结论: 使用深拷贝时,如果子对象为可变数据类型,父对象和子对象都不同;如果子对象为不可变类型,子对象相同,父对象根据父对象的数据类型而定。

3 举例说明

import copy

a = [1, ['a', 'b']]
b = a
c = a.copy()
d = copy.deepcopy(a)

print(a is b)
print(a is c)
print(a is d)

print(a[0] is b[0])
print(a[0] is c[0])
print(a[0] is d[0])

a.append(5)   # 增加父对象中的元素
print(a)
print(b)
print(c)
print(d)

a[0] = 6   # 修改父对象中的元素
print(a)
print(b)
print(c)
print(d)

a[1].append('c')   # 增加子对象中的元素
print(a)
print(b)
print(c)
print(d)

''' 输出结果 '''
True      # b和a指向同一个父对象
False     # c、d与a指向不同的父对象
False
True
True      # a、c指向相同的子对象
False
[1, ['a', 'b'], 5]
[1, ['a', 'b'], 5]
[1, ['a', 'b']]
[1, ['a', 'b']]
[6, ['a', 'b'], 5]   # a[0]指向新的子对象
[6, ['a', 'b'], 5]
[1, ['a', 'b']]      # c[0]仍指向原来的子对象
[1, ['a', 'b']]
[6, ['a', 'b', 'c'], 5]
[6, ['a', 'b', 'c'], 5]
[1, ['a', 'b', 'c']]   # c和a的子对象相同
[1, ['a', 'b']]

注意: 在Python中,根本没有办法删除值。 使用 del 只能删除对象名称。当一个值(放在内存空间)没有对象名称与之关联时,Python解释器会直接将其删掉,称为 “垃圾收集”。

x = 1
y = x
z = x
x += 1        # x指向新的值
del y         # 删除变量名y
print(x, z)   # z指向的值(内存空间)还在原位
print(y)

''' 输出结果 '''
2 1
Traceback (most recent call last):
  File "/home/.../test.py", line 7, in <module>
    print(y)
NameError: name 'y' is not defined

参考资料

菜鸟教程. Python 直接赋值、浅拷贝和深度拷贝解析.
xzw96. Python 深拷贝和浅拷贝详解. 优快云博客.
时代&信念. Python中的浅拷贝和深拷贝(一看就懂!!!). 优快云博客.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎猫骑巨兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值