Python 提供浅拷贝与深拷贝两种方式复制对象,它们在引用共享和内存占用上的差异,会影响程序的稳定性与数据安全。

通俗来说,浅拷贝像拍快照,只记录表层;深拷贝则像克隆,连内部结构也一并复制。

一、浅拷贝

浅拷贝(Shallow Copy)会创建一个新对象,但内部元素(子对象)依然是原对象的引用。

它只复制“外层容器”,不递归复制内部可变对象。

1、特点

(1)修改副本对象的外层结构(添加、删除元素)不会影响原对象。

(2)修改副本对象的内部子对象会影响原对象(因为共享引用)。

2、常用方法

列表:

new_list = old_list.copy() 
# 或 
list(old_list)

字典:

new_dict = old_dict.copy()

集合:

new_set = old_set.copy()

通用方法:使用标准库

import copy

new_obj = copy.copy(old_obj)

3、示例

import copy

a = [1, 2, [3, 4]]
b = copy.copy(a)   # 浅拷贝

a[2].append(5)     # 修改子列表对象
print(a)  # [1, 2, [3, 4, 5]]
print(b)  # [1, 2, [3, 4, 5]]  <- 子列表被共享

结果解读:

外层列表是独立的,但内部子列表依旧共享引用,所以两者的内部数据一起变化。

二、深拷贝

深拷贝(Deep Copy)会创建一个新对象,并递归地复制内部所有子对象,形成完全独立的副本。

1、特点

(1)修改新对象的任何层级都不会影响原对象。

(2)占用更多内存,执行速度比浅拷贝慢。

(3)自动处理循环引用,防止无限递归。

2、常用方法

import copy

new_obj = copy.deepcopy(old_obj)

3、示例

import copy

a = [1, 2, [3, 4]]
c = copy.deepcopy(a)  # 深拷贝

a[2].append(5)        # 修改子列表
print(a)  # [1, 2, [3, 4, 5]]
print(c)  # [1, 2, [3, 4]]  <- 完全独立

结果解读:

因为深拷贝递归复制了子对象,所以修改原对象的子列表不会影响副本。

三、 赋值 vs 浅拷贝 vs 深拷贝

1、可视化引用关系

假设有对象:

a = [1, [2, 3]]

赋值:b = a

a ──▶ [1, ──▶ [2, 3]]
b ──┘

浅拷贝:copy.copy(a)

a ──▶ [1, ──▶ [2, 3]]
b ──▶ [1, ──┘]

深拷贝:copy.deepcopy(a)

a ──▶ [1, ──▶ [2, 3]]
b ──▶ [1, ──▶ [2, 3]](新对象)

2、应用场景对比

四、补充说明

1、不可变对象(如 int、float、str、tuple 等)在浅拷贝和深拷贝下效果相同。

2、性能差异

深拷贝递归复制所有子对象,速度较慢,内存占用更高。

3、循环引用

copy.deepcopy 会自动处理循环引用,防止无限递归。

4、自定义类

如果类实现了 __copy__ 或 __deepcopy__,copy 模块会优先调用它们。

5、选择建议

在需要完全隔离数据的场景下使用深拷贝,其他情况优先浅拷贝以提高性能。

点赞有美意,赞赏是鼓励