Published on

Python 中的深拷贝与浅拷贝

Authors

最近深入研究了一下 Python 对象的复制机制,这里发表一下。

Python 与 C++ 的对比

Python 中的 deepcopy 有点类似于 C++中的 复制构造函数,只不过 Python 中的 deepcopy 要比 C++ 中的复制构造函数简单的多的多。

在 C++ 中有三大函数: 默认构造函数、复制构造函数、析构函数,如果一个对象中用到了堆内存,如果要实现这个对象的正常拷贝,那么这个类必须实现 复制构造函数=操作符重载。并且这个地方,也是 C++ 的一个难点,幸好 Python 已经内置了实现对象拷贝的方法。

示例代码

用一段代码来说明 deepcopycopy 的区别:

import copy

class Tree:
    def __init__(self, age=None, high=None, name=None):
        self.age = age
        self.hight = high
        self.name = name
        self.func = []

## example of copy
T1 = Tree(12, 15, 'oak')
T1.func.append('desk')

print(T1.age, T1.hight, T1.name, T1.func)

T2 = copy.copy(T1)

T2.func.append('bed')
T2.age = 10

print("T1:", T1.age, T1.hight, T1.name, T1.func)
print("T2:", T2.age, T2.hight, T2.name, T2.func)

## example of deepcopy
T3 = Tree(10, 12, 'palm')
T3.func.append('oil')

print(T3.age, T3.hight, T3.name, T3.func)

T4 = copy.deepcopy(T3)

T4.func.append('shadow')
print("T3:", T3.age, T3.hight, T3.name, T3.func)
print("T4:", T4.age, T4.hight, T4.name, T4.func)

代码输出结果:

> 12 15 oak ['desk']
> T1: 12 15 oak ['desk', 'bed']
> T2: 10 15 oak ['desk', 'bed']
> 10 12 palm ['oil']
> T3: 10 12 palm ['oil']
> T4: 10 12 palm ['oil', 'shadow']

可以看到,不管是 copy 还是 deepcopy 都会构造一个新的对象,但是,遇到引用,deepcopy 会继续复制引用的内容。从上例可以看出,copy 并没有把列表复制一份,而只是用了原来列表的引用。