2025-10-22
python
00
请注意,本文编写于 47 天前,最后修改于 47 天前,其中某些信息可能已经过时。

目录

深拷贝与浅拷贝的区别
基本概念
浅拷贝 (Shallow Copy)
深拷贝 (Deep Copy)
Python中的实现方式
关键区别演示
不同数据类型的拷贝行为
不可变对象
可变对象
面试中常见问题
1. 什么时候用浅拷贝?什么时候用深拷贝?
2. 如何判断是否需要深拷贝?
3. 性能考虑
总结表格
实际测试案例

深拷贝与浅拷贝的区别

基本概念

浅拷贝 (Shallow Copy)

  • 创建一个新对象,但只复制原对象的顶层结构
  • 对于嵌套对象,只复制引用而不创建新对象
  • 原对象和拷贝对象会共享嵌套的可变对象

深拷贝 (Deep Copy)

  • 创建一个完全独立的新对象
  • 递归复制所有嵌套对象,创建全新的对象结构
  • 原对象和拷贝对象完全不共享任何可变对象

Python中的实现方式

python
import copy # 原始数据 original_list = [1, 2, [3, 4], {'a': 5}] # 浅拷贝 shallow_copied = copy.copy(original_list) # 或者使用列表的copy()方法 shallow_copied2 = original_list.copy() # 或者使用切片 shallow_copied3 = original_list[:] # 深拷贝 deep_copied = copy.deepcopy(original_list)

关键区别演示

python
import copy # 原始列表包含嵌套列表 original = [1, 2, [3, 4]] # 浅拷贝 shallow = copy.copy(original) # 深拷贝 deep = copy.deepcopy(original) print("原始ID:", id(original), "嵌套列表ID:", id(original[2])) print("浅拷贝ID:", id(shallow), "嵌套列表ID:", id(shallow[2])) print("深拷贝ID:", id(deep), "嵌套列表ID:", id(deep[2])) # 修改原始列表的嵌套元素 original[2][0] = 999 print("\n修改后:") print("原始:", original) # [1, 2, [999, 4]] print("浅拷贝:", shallow) # [1, 2, [999, 4]] - 被影响! print("深拷贝:", deep) # [1, 2, [3, 4]] - 不受影响

输出结果:

原始ID: 140245120000000 嵌套列表ID: 140245120000016 浅拷贝ID: 140245120000032 嵌套列表ID: 140245120000016 深拷贝ID: 140245120000048 嵌套列表ID: 140245120000064 修改后: 原始: [1, 2, [999, 4]] 浅拷贝: [1, 2, [999, 4]] 深拷贝: [1, 2, [3, 4]]

不同数据类型的拷贝行为

不可变对象

python
import copy # 对于不可变对象,浅拷贝和深拷贝效果相同 tup1 = (1, 2, 3) tup2_copy = copy.copy(tup1) tup2_deep = copy.deepcopy(tup1) print(id(tup1) == id(tup2_copy)) # True - Python会优化,重用对象 print(id(tup1) == id(tup2_deep)) # True

可变对象

python
import copy # 字典的拷贝 dict_original = {'a': 1, 'b': [2, 3]} dict_shallow = copy.copy(dict_original) dict_deep = copy.deepcopy(dict_original) dict_original['b'][0] = 999 print("原始:", dict_original) # {'a': 1, 'b': [999, 3]} print("浅拷贝:", dict_shallow) # {'a': 1, 'b': [999, 3]} - 被影响 print("深拷贝:", dict_deep) # {'a': 1, 'b': [2, 3]} - 不受影响

面试中常见问题

1. 什么时候用浅拷贝?什么时候用深拷贝?

浅拷贝适用场景:

  • 对象没有嵌套的可变对象
  • 你希望共享嵌套对象以节省内存
  • 性能要求较高(深拷贝更耗时)

深拷贝适用场景:

  • 需要完全独立的对象副本
  • 嵌套对象需要独立修改
  • 在多线程环境中避免竞态条件

2. 如何判断是否需要深拷贝?

检查对象是否包含嵌套的可变对象(列表、字典、集合等),如果有且需要独立修改,则使用深拷贝。

3. 性能考虑

python
import copy import time large_list = [[i for i in range(1000)] for _ in range(1000)] # 浅拷贝性能测试 start = time.time() shallow_copy = copy.copy(large_list) print(f"浅拷贝时间: {time.time() - start:.4f}秒") # 深拷贝性能测试 start = time.time() deep_copy = copy.deepcopy(large_list) print(f"深拷贝时间: {time.time() - start:.4f}秒")

总结表格

特性浅拷贝深拷贝
复制层级只复制顶层递归复制所有层级
嵌套对象共享引用创建新对象
内存使用较少较多
性能较快较慢
独立性嵌套对象不独立完全独立
适用场景无嵌套可变对象或需要共享需要完全独立的副本

实际测试案例

作为测试工程师,理解这些概念对于:

  1. 测试数据准备时避免意外修改
  2. 理解函数参数传递的影响
  3. 在多线程测试中确保数据隔离
  4. 性能测试时选择合适的数据复制方式
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:李佳玮

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!