python深拷贝一个对象_Python中深拷贝、浅拷贝问题

有一次面试的时候被问到了,记录一下。

python中对于对象的拷贝分为两种方式:深拷贝和浅拷贝。浅拷贝用‘=’实现,深拷贝则使用deepcopy()函数完成。浅拷贝和深拷贝的区别是:浅拷贝只是将原对象在内存中引用地址拷贝过来了,让新的对象指向这个地址,这样新对象与原对象指向的地址相同;而深拷贝是将这个对象的所有内容拷贝过来了,包括值与内存地址,所以如果你这时候修改原来对象的值跟新对象没关系了,不会随之更改。

举个栗子。

先看浅拷贝

# 1.使用=复制不可变对象的值。

a = 1

b = a

print("a is :{0},b is :{1}".format(a, b)) # a is :1,b is :1

print(id(a), id(b)) # 2012967568 2012967568 此时a,b指向相同内存地址

# 这时候修改a的值,因为a是不可变类型,修改其值,会重新给新值分配内存,然后指向他。

a += 1

print(a, id(a), b, id(b)) # 2 2012967600 1 2012967568 值不一样,内存地址也不一样了

# 1.使用=复制可变对象的值。

ls1 = [1, 2, 3, 4]

ls2 = ls1

print("ls1 is :{0},ls2 is :{1}".format(ls1, ls2)) # ls1 is :[1, 2, 3, 4],ls2 is :[1, 2, 3, 4]

print(id(ls1), id(ls2)) # 1815774582984 1815774582984 直接使用=复制变量,内存地址一样,值也一样。

# 这时候修改可变对象的值,因为其值可变,所以只需要在原内存地址上修改即可。

ls1.append(5)

print(id(ls1), id(ls2)) # 1815774582984 1815774582984 可变对象修改其值,内存引用不变

print(ls1, ls2) # [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] 因为两个变量的内存指向一样,所以值也一样。

再看深拷贝

# 1.使用copy.deepcopy()拷贝不可变对象的值。

a = 1

b = copy.deepcopy(a)

print("a is :{0},b is :{1}".format(a, b)) # a is :1,b is :1

print(id(a), id(b)) # 2012967568 2012967568 对于不可变对象,深度拷贝内存地址没有修改。

a += 1

print(a, id(a), b, id(b)) # 2 2012967600 1 2012967568 值不一样,内存地址也不一样了

# 1.使用copy.deepcopy()复制可变对象的值。

ls1 = [1, 2, 3, 4]

ls2 = copy.deepcopy(ls1)

print("ls1 is :{0},ls2 is :{1}".format(ls1, ls2)) # ls1 is :[1, 2, 3, 4],ls2 is :[1, 2, 3, 4]

print(id(ls1), id(ls2)) # 2585490905224 2585490905032 注意对于可变对象深度拷贝后内存地址不一样了。

ls1.append(5)

print(id(ls1), id(ls2)) # 2585490905224 2585490905032

print(ls1, ls2) # [1, 2, 3, 4, 5] [1, 2, 3, 4] 注意这个时候ls2的值没有随着ls1修改。

总结:其实对于浅拷贝和深拷贝来说,如果拷贝对象都是不可变对象的话,那么两者效果是一样的。如果是可变对象的话,“=”拷贝的方式,只是拷贝了内存中的地址引用,两个对象的地址引用一样,所以两个对象的值会随着一方的修改而修改。而对于deepcopy()来说,如果是可变对象的话,那么拷贝内容后新对象的内存地址也会重新分配,跟原来的内存地址不一样了,所以两者任意修改变量的内容不会对另一方造成影响。

参考:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值