Python深拷贝与浅拷贝机制详解及代码对比

Oliver
Oliver
发布时间:2026-10-13 | 4人浏览过
原创

本文详细解析Python中深拷贝与浅拷贝的核心区别。通过对比直接赋值、list.copy()、copy.copy()及copy.deepcopy()四种方式,结合内存地址与子对象变化示例,阐明父对象与子对象的拷贝行为差异,帮助开发者避免可变对象引用的潜在Bug。

Python深拷贝与浅拷贝机制详解

本文深入解析Python中深拷贝(deep copy)与浅拷贝(shallow copy)的区别,并通过具体代码示例进行详细对比。内容涵盖对象引用、内存地址变化及子对象处理机制,对理解Python数据复制机制具有实际参考价值。

基础代码示例与结果分析

首先通过一段基础代码来直观展示不同拷贝方式的行为。


import copy
 
a = [1, 2, 3, [4]]
b = a
c = a.copy()
d = copy.deepcopy(a)
e = copy.copy(a)
a.append(4)
a[3].append(5)
print('a值为 {} 地址为 {}'.format(a, id(a)))
print('b值为 {} 地址为 {}'.format(b, id(b)))
print('c值为 {}  地址为 {}'.format(c, id(c)))
print('d值为 {}    地址为 {}'.format(d, id(d)))
print('e值为 {}  地址为 {}'.format(e, id(e)))

运行上述代码后的输出结果如下:


a值为 [1, 2, 3, [4, 5], 4] 地址为 4555940360
b值为 [1, 2, 3, [4, 5], 4] 地址为 4555940360
c值为 [1, 2, 3, [4, 5]]  地址为 4555873544
d值为 [1, 2, 3, [4]]    地址为 4556227912
e值为 [1, 2, 3, [4, 5]]  地址为 4556227464

从输出结果中可以观察到以下关键现象:

变量b直接赋值为a,此时b仅持有a的内存地址引用。因此,当a的内容发生变化时,b的值也会随之改变,这属于直接赋值(对象引用)行为。

变量c通过调用a.copy()方法生成。结果显示,c的内存地址与a不同,且c的值不随a的变化而变化。这表明c完全复制了父对象及其内部子对象,属于深拷贝(deep copy)行为。

变量d和e分别使用Python标准库copy模块中的deepcopy()和copy()方法生成,具体代码如下:

变量d通过deepcopy()生成,其内存地址与a不一致,且值不随a变化。这同样是深拷贝,完整复制了父对象及其所有层级的子对象。

变量e通过copy()生成,表现为浅拷贝(shallow copy)。虽然父级内容的内存地址与a不同,值不随a变化,但e内部的子列表内容与a的子列表共享同一内存地址。因此,当a的子对象发生变化时,e的子对象内容也会随之改变。


print('a子对象值为 {} 地址为 {}'.format(a[3], id(a[3])))
print('e子对象值为 {} 地址为 {}'.format(a[3], id(a[3])))
结果:
a子对象值为 [4, 5] 地址为 4334486344
e子对象值为 [4, 5] 地址为 4334486344

三种拷贝行为总结

综上所述,Python中的拷贝操作主要可分为以下三种类型:

1、直接赋值:即对象引用,新旧变量指向同一内存地址。

2、浅拷贝:仅复制父对象,不递归复制内部的子对象。父子对象地址不同,但子对象地址相同。

3、深拷贝:完全复制父对象及其所有层级的子对象,新旧对象及其子对象均拥有独立的内存地址。

以上内容为本文全部解析,希望能为读者在Python编程中正确处理数据拷贝提供有益帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表