这篇文章以 list,dict,class 为例,带你了解 Python 中的浅拷贝与深拷贝。
变量与指针
在理解下面的例子之前,我们需要对 Python 中的变量有一个基本的理解。
对变量赋值,在其他语言中,我们可能理解为开辟一个区域(理解为容器、或者是一个篮子),再将值放进去。
1 | // C 语言:在内存中开辟一个区域,将值放进去 |
在 Python 中,写法是一样的,但是最好的理解是将一个指针指向了这个区域:
1 | # Python:定义了一个指针 x,指向了内存中 |
因为 Python 变量相当于一个指针,指向这个内存区域,所以无需提前声明好变量是什么类型,指针中间也可以指向别的值,这也是人们说的 Python 的动态类型。
所以你可以这么做:
1 | x = 1 # x is an integer |
但是动态类型也有缺点,那就是如果两个变量名指向同一个数据,那么一个变量所做的修改,另一个变量所指向的值也会发生变化。
下面来看具体的例子:
以 list 为例
1 | # ---------------- 浅拷贝 ------------------ # |
上面代码的输出:
1 | --------- New List XS, YS |
以 dict 为例
1 | # 新建一个 dict,用来演示深拷贝与浅拷贝 |
上面代码的输出:
1 | A new dict: {'name1': {'scott zhang': 1}, 'name2': {'the weeknd': 2}} |
以 class 为例
1 | import copy |
上面代码的输出:
1 | ---- Point |
总结
- 浅拷贝(shallow copy)并不会克隆对象中的子对象,因此原对象和对象中,被拷贝的内部对象不是独立两份,而是同一份。
- 深拷贝(Deep copy)会递归的拷贝所有子对象,这保证了内部对象的独立性,但是这样速度很慢。
- 你可以使用 copy 模块拷贝任意对象(包括你自定义的类),你还可以通过实现
__copy()__
或__deepcopy()__
来自定义拷贝的过程。