Python中的赋值引用、浅拷贝、深拷贝小结

有部分参考资料:https://blog.csdn.net/w494675608/article/details/82114798

引用传递:传递的是实际参数的地址,内存地址时不同的,可变对象是引用传递。

值传递:传递的是值,内存地址是一样的,不可变对象是值传递。

赋值:将一个对象的地址赋值给另外一个对象,两者的内存地址时相同的(值传递)

浅拷贝和深拷贝的共同点:都是在内存中开辟了另一块内存地址。

from copy import copy,deepcopy

l = [1,2,3,4,[1,2,3]]
new_l = l
copy_l = copy(l)
deepcopy_l = deepcopy(l)

print('l',id(l))
print('new_l',id(new_l))
print('copy_l',id(copy_l))
print('deepcopy_l',id(deepcopy_l))

l 12727752
new_l 12727752
copy_l 12401416
deepcopy_l 12727432 

从上面的结果可以看出 l 与被赋值对象 new_l的内存地址时一样的,浅拷贝和深拷贝 后的对象的内存地址与原始数据的内存地址都不一样,在内存中开辟了一块新的内存空间。

现在分别来看对象中的不可变元素的id值和可变元素的id值

print('l[1]',id(l[1]),'l[-1]',id(l[-1]))
print('new_l[1]',id(new_l[1]),'new_l[-1]',id(new_l[-1]))
print('copy_l[1]',id(copy_l[1]),'copy_l[-1]',id(copy_l[-1]))
print('deepcopy_l[1]',id(deepcopy_l[1]),'deepcopy_l[-1]',id(deepcopy_l[-1]))

结果:
l[1] 1488257552 l[-1] 12729672
new_l[1] 1488257552 new_l[-1] 12729672
copy_l[1] 1488257552 copy_l[-1] 12729672
deepcopy_l[1] 1488257552 deepcopy_l[-1] 12729480

从上面的运行结果可以看出:

1.赋值:将原始对象的地址赋值给一个新变量,新变量的地址指向原始对象的地址,变量中的元素地址与原始对象中的元素地址是相同的。

2.浅拷贝:在内存中的另一块地址中创建一个新的变量,浅拷贝创建的新变量中的元素与原始对象中的元素地址是相同的

3.深拷贝:在内存中的另一块地址中创建一个新的变量,深拷贝创建的新变量中 不可变元素与原始对象中的不可变元素的地址相同,但是可变元素与原始对象中的可变元素的地址时不同的,也就是进行了深层次的拷贝。

l.append(9)
print(copy_l)
print(l)

# 结果
[1, 2, 3, 4, [1, 2, 3]]
[1, 2, 3, 4, [1, 2, 3], 9]

如果改变原始数据中的不可变元素,浅拷贝创建的变量copy_l,值不会改变,如果改变原始数据中的可变元素,浅拷贝创建的变量,值是会相应的改变。

l[-1].append(9)
print(copy_l)
print(l)

# 结果
[1, 2, 3, 4, [1, 2, 3, 9]]
[1, 2, 3, 4, [1, 2, 3, 9]]

浅拷贝创建的对象,改变该对象中的不可变元素,对原始数据不会产生影响,改变该对象中的可变元素,原始数据也会改变。

copy_l[-1].append(9)
print(l)
print(copy_l)

# 结果
[1, 2, 3, 4, [1, 2, 3, 9]]
[1, 2, 3, 4, [1, 2, 3, 9]]

copy_l.append(9)
print(l)
print(copy_l)
#  结果
[1, 2, 3, 4, [1, 2, 3]]
[1, 2, 3, 4, [1, 2, 3], 9]

小结浅拷贝:浅拷贝创建的对象 中的元素地址与原始对象中的元素地址是相同的,那么两者是相互影响的,只要其中任意一个对象中的可变元素改变,另一个对象也会改变。

new_l = l
copy_l = copy(l)
deepcopy_l = deepcopy(l)
l[-1].append(10)
print(l)
print(deepcopy_l)
# 结果
[1, 2, 3, 4, [1, 2, 3, 10]]
[1, 2, 3, 4, [1, 2, 3]]

小结深拷贝:在内存中开辟另外一块空间,深拷贝创建的对象地址与原始对象地址不同,但是该对象中的不可变元素与原始对象中的不可变元素地址相同,而可变地址不同,也就是说,无论是原始对象改变还是该对象改变,都不会影响对方的值。是完全的副本。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值