Python中的赋值与拷贝

在经过多次尝试之后,终于基本弄清了python中的拷贝和赋值的原理,总体来说,个人觉得不像C++那么讲道理,但并不是无章可循。

首先,最重要的是赋值的原理,也是能解释下面所有内容的关键:b=a的含义是将a指向的变量的地址复制给b。当变量是一个值,b就会指向这个值的地址;当a指向的变量是一个列表、元组或者字典,b就指向列表、元组或者字典的地址。

问题变的清楚了,看下面的代码:

a = 1
b = a
a = 2
b
a = [1,2]
b = a
a.append(3)
b

输出分别为:

1
[1,2,3]
很明显,a=2使得 a指向了2的地址(即a指向了一个新的地址),所以b的值并没有受到影响。

但a=[1,2],b=a后,b和a指向了同一个列表的地址,并没有指向列表的所有元素,因此修改a的列表元素后,b相应的也会发生变化。

为了保证a和b列表间不会相互影响,这里首先引入浅拷贝的概念:

a=[1,2]
b = a.copy()
a.append(3)
b

对应输出为:

[1,2]

浅拷贝原理是开辟一个新的空间,将a指向的变量拷贝到新空间,让b指向这个新空间的变量。但是这里仍会有问题:

a = [[1,2],3]
b = a.copy()
a[0][0]=2 #a=[[2,2],3]
b

结果为:

[[2,2],3]

当a指向的变量(起个名字叫子变量)指向变量(这里就叫做孙变量吧)时,浅拷贝并不会把孙变量一并拷贝,而是拷贝了指向孙变量的子变量——指针。这样结果就很好理解了。

为了解决这个问题,需要引入深拷贝

import copy
a = [[1,2],3]
b = copy.deepcopy(a)
a[0][0]=2
b

此时的输出已经变为:

[[1,2],3]

并且经过测试,a的变量深度再加深,深拷贝结果仍然正确。

字典的情况与列表类似,我们可以认为字典的key和value分别对应两个数组即可。

利用这个性质,我们可以将类的私有字典通过=赋值的方式传递出去。


猜你喜欢

转载自blog.csdn.net/weixin_38082364/article/details/79781108
今日推荐