python 变量赋值是引用和拷贝_你真的知道Python中的赋值与拷贝吗?

深拷贝

深拷贝就是在每个层次都对可变对象进行拷贝,浅拷贝只对最外层可变对象进行拷贝。

我们先来看看赋值的情况即b = a,如下图所示:(灵魂画手终于上场···)

19e5548265f21748b7ee1d24c5bf8f59.png

示意图a与b指向同一个对象,我们通过代码验证其正确性:

交互式Python代码:

>>> a = [1, 2, [3, 4]]

>>> b = a

>>> id(b) == id(a)

True

>>> id(a[0]) == id(b[0])

True

>>> id(a[1]) == id(b[1])

True

>>> id(a[2]) == id(b[2])

True

>>> id(a[2][0]) == id(b[2][0])

True

>>> id(a[2][1]) == id(b[2][1])

True

再来看看浅拷贝的情况,先上图:

5fa4dae0857dd75a6e257f10c24037aa.png

上图中为b = a[:]示意图,b为a的浅拷贝,浅拷贝会将最外层可变对象进行拷贝,下面进行代码验证:

交互式Python代码:

>>> a = [1, 2, [3, 4]]

>>> b = a[:]

>>> id(b) == id(a)

False

>>> id(a[0]) == id(b[0])

True

>>> id(a[1]) == id(b[1])

True

>>> id(a[2]) == id(a[2])

True

>>> id(a[2][0]) == id(b[2][0])

True

>>> id(a[2][1]) == id(b[2][1])

True

最后来看看深拷贝,深拷贝我们需要用到copy库的deepcopy,示意图如下:

dd15ac4eee7463b77eea7ccfd186b262.png

接下来进行代码验证:

交互式Python代码:

>>> from copy import deepcopy

>>>

>>> a = [1, 2, [3, 4]]

>>> b = deepcopy(a)

>>> id(a) == id(b)

False

>>> id(a[0]) == id(b[0])

True

>>> id(a[1]) == id(a[1])

True

>>> id(a[2]) == id(b[2])

False

>>> id(a[2][0]) == id(b[2][0])

True

>>> id(a[2][1]) == id(b[2][1])

True

因此当实参为可变对象且其中含有多层嵌套的可变对象时,如果我们不想因为我们的粗心让函数更改实参,那么我们就应该使用深拷贝,看代码:

交互式Python代码:

>>> a = [1, 2, [3, 4]]

>>> def func(List):

List.append('hello world')

List[0] = 'shawn'

List[2][0] = 'simon'

List[2][1] = 199

return List

>>> from copy import deepcopy

>>> b = func(deepcopy(a))

>>> a

[1, 2, [3, 4]]

>>> b

['shawn', 2, ['simon', 199], 'hello world']

Note: Python中的深拷贝和浅拷贝只是针对可变对象而言,而对于不可变对象无所谓深拷贝还是浅拷贝,因为对于不可变对象两种拷贝和变量之间赋值没什么两样。

交互式Python代码:

>>> from copy import deepcopy

>>>

>>> a = 'hello world'

>>> b = deepcopy(a)

>>> c = a

>>> id(a) == id(b) == id(c)

True

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值