前言:很多同学在学习深拷贝、浅拷贝对二者不是很清楚,下面是我对深拷贝、浅拷贝的认识,希望可以帮助到你理解。
首先我们要知道一点,在Python中没有赋值这一概念,可以说Python中一切皆引用。可以看一下面这段代码,i和3拥有相同内存地址。
In [1]: i = 3
In [2]: i
Out[2]: 3
In [3]: id(i)
Out[3]: 10919488
In [4]: id(3)
Out[4]: 10919488
接着我们说一下拷贝的意义,既然python中一切皆引用,那么我们就应该知道拷贝的意义其实就是把要拷贝的内容复制一份,
1.浅拷贝是也叫顶层拷贝,只拷贝被拷贝对象的最顶层,如果最顶层是可变对象时,我们则从新在内存中开辟一个内存空间存储最顶层一下的所有引用,看代码
In [6]: import copy
In [7]: i = [(1,[2]),]
In [8]: j = copy.copy(i)
In [9]: j
Out[9]: [(1, [2])]
In [10]: id(i)
Out[10]: 139788733755528
In [11]: id(j)
Out[11]: 139788733781512
In [12]: id(i[0])
Out[12]: 139788785521096
In [13]: id(j[0])
Out[13]: 139788785521096
2.对于顶层是不可变类型,即使内部存在可变数据类型也不会在内存中开辟新的内存空间,而是直接复制被拷贝对象的应用,看代码:
i = ([1,(2,)],(1,))
In [15]: j = copy.copy(i)
In [16]: j
Out[16]: ([1, (2,)], (1,))
In [17]: id(i)
Out[17]: 139788733780936
In [18]: id(j)
Out[18]: 139788733780936
小总结:对于浅拷贝而言,我们只要看被拷贝对象的最顶层是不是可变数据类型就可以,是可变则开辟新新空间存储,不是则直接把被拷贝对象引用拿来。
接下来我们来说深拷贝,深拷贝是递归拷贝,首先我们判断的是被拷贝对象是不是全是不可变类型,注意“全是”:包含所有的子对象。如果全是不可变类型同样的也是直接把被拷贝对象的引用直接拿来用,看代码:
In [19]: i = ((1,),(2,3))
In [20]: j = copy.deepcopy(i)
In [21]: j
Out[21]: ((1,), (2, 3))
In [22]: id(i)
Out[22]: 139788733696520
In [23]: id(j)
Out[23]: 139788733696520
而只要当前数据的子数据中存在可变数据类型,都会对当前数据进行重新开辟内存空间存储,无论当前数据类型是否可变,看代码
In [24]: i = ([1],(2,))
In [25]: j = copy.deepcopy(i)
In [26]: id(i)
Out[26]: 139788733709768
In [27]: id(j)
Out[27]: 139788733798216
In [28]: id(i[0])
Out[28]: 139788733758536
In [29]: id(j[0])
Out[29]: 139788733704392
In [30]: id(j[1])
Out[30]: 139788716644784
In [31]: id(i[1])
Out[31]: 139788716644784
小总结:对于深拷贝而言,要仔细把握被拷贝对象是否为可变数据类型就好。