为了账号安全,请及时绑定邮箱和手机立即绑定

深入理解Python中赋值、深拷贝(deepcopy)、浅拷贝(copy)

标签:
Python

赋值

python跟java中的变量本质是不一样的,Python的变量实质上是一个指针(int型或str型),而java的变量是一个可操作的存储空间。

复制代码

a = 123
b = a

print(id(a))
print(id(b))

print(a is b)


result:

  26848576
  26848576
  True

复制代码

这里可以看到a和b的地址是一样的,a=123,实质上是将a这个对象"贴到"123上;同样,b=a,也是将b这个对象“贴到”123上,这里变量实际上是个“便利贴“。

下面用一个可变的对象list来做说明:

复制代码

a = [1, 2, 3]
b = a

a.append(4)
a[0] = 6print(a)print(b)

result:
[6, 2, 3, 4]
[6, 2, 3, 4]

复制代码

首先把a和b贴在 [1,2,3]这个对象上,然后通过append,[1,2,3]这个对象变成了[1,2,3,4],再通过a[0]=6,将对象[1,2,3,4]的第0个元素地址对应值改为6,

则最终这个对象是[6,2,3,4],然而a和b仍然是贴在这个对象上的,即a和b都是[6,2,3,4]

 

 

浅拷贝(copy)

对于浅拷贝有两种情况:

1. 浅拷贝值是不可变对象(数值,字符串,元组)时,等同于赋值,对象的id值与浅拷贝原来的值相同。

 

复制代码

import copy

a = 1b = a
c = copy.copy(a)print(id(a))print(id(b))print(id(c))

result:35258712
35258712
35258712

复制代码

 

 

 

2. 浅拷贝值是可变对象(list,dict)时:

 2.1 不包含子对象

复制代码

# coding:utf-8import copy

a = [1, 2, 3]
b = a
c = copy.copy(a)print("append前c={}".format(id(c)))
a.append(4)print("a={}".format(id(a)))print("b={}".format(id(b)))print("append后c={}".format(id(c)))print("a值={}".format(a))print("b值={}".format(b))print("c值={}".format(c))


result:
append前c=139982846485352a=139982846912272b=139982846912272append后c=139982846485352a值=[1, 2, 3, 4]
b值=[1, 2, 3, 4]
c值=[1, 2, 3]

复制代码

对于不包含子对象的情况下,原值的改变并不会影响浅拷贝的值,同时浅复制的值改变也并不会影响原值,并且浅拷贝是新开辟的一块内存,与原对象内存地址不同。

 

 2.2 包含子对象

复制代码

# coding:utf-8import copy

a = [1, [4], 2, 3]
b = a
c = copy.copy(a)print("append前c={}".format(id(c)))
a.append(5)
a[1].append(9)print("a={}".format(id(a)))print("b={}".format(id(b)))print("append后c={}".format(id(c)))print("a值={}".format(a))print("b值={}".format(b))print("c值={}".format(c))


result:
append前c=140519703466856a=140519703889752b=140519703889752append后c=140519703466856a值=[1, [4, 9], 2, 3, 5]
b值=[1, [4, 9], 2, 3, 5]
c值=[1, [4, 9], 2, 3]

复制代码

 可以看出,浅拷贝只拷贝父对象([1,2,3]),不会拷贝对象内部的子对象([4]),改变原对象中复杂子对象的值时会改变浅拷贝的值。

 

 

深拷贝(deepcopy)

 

复制代码

# coding:utf-8import copy

a = [1, [4], 2, 3]print("a原始值={}".format(a))
b = a
d = copy.deepcopy(a)

a.append(5)
a[1].append(9)print("a={}".format(id(a)))print("b={}".format(id(b)))print("d={}".format(id(d)))print("a值={}".format(a))print("b值={}".format(b))print("d值={}".format(d))


result:
a原始值=[1, [4], 2, 3]
a=139675956164440b=139675956164440d=139675955741904a值=[1, [4, 9], 2, 3, 5]
b值=[1, [4, 9], 2, 3, 5]
d值=[1, [4], 2, 3]

复制代码

 

深拷贝则会拷贝对象及其子对象,深拷贝的时候会将复杂对象的每一层复制一个单独的个体出来,原对象的值改变时并不会影响deepcopy的值,

但是,由于深拷贝需要维护一个 内存 用于记录已经拷贝的对象,所以深拷贝的速度会比较慢。

原文出处:https://www.cnblogs.com/FG123/p/9463390.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消