Python数据拷贝方式区别_浅拷贝与深拷贝解析【教程】

Python中数据拷贝需区分浅拷贝与深拷贝:浅拷贝仅复制顶层对象,嵌套子对象仍共享引用;深拷贝递归复制所有层级,完全独立。常用方法分别为copy.copy()和copy.deepcopy()。

Python中数据拷贝不是简单赋值,直接用等号(=)只是创建新引用,原对象和副本指向同一内存地址。真正复制需要浅拷贝或深拷贝,二者核心区别在于:浅拷贝只复制最外层对象,嵌套的子对象仍共享;深拷贝递归复制所有层级,完全独立。

什么是浅拷贝?

浅拷贝生成一个新对象,但只复制顶层元素。如果原对象包含可变类型(如列表、字典、自定义类实例),这些嵌套对象在副本中仍是原对象的引用。

  • 常用方法:copy.copy()list.copy()dict.copy()、切片 [:]
  • 适用场景:对象结构扁平,或确认嵌套部分不会被修改
  • 例子:
    import copy
    a = [1, [2, 3]]
    b = copy.copy(a) # 浅拷贝
    b[0] = 99 # 修改顶层 → a 不变
    b[1].append(4) # 修改嵌套列表 → a[1] 也变成 [2, 3, 4]

什么是深拷贝?

深拷贝递归遍历整个对象树,为每个子对象都创建独立副本。修改副本任意层级,都不会影响原始对象。

  • 唯一标准方法:copy.deepcopy()
  • 适用场景:含多层嵌套、需彻底隔离的结构(如配置字典、树形数据、类实例含可变属性)
  • 注意点:
    - 性能开销明显更大,尤其对大型嵌套结构
    - 不支持某些内置对象(如文件句柄、线程锁)和自定义类若未正确定义 __getstate____reduce__
    - 遇到循环引用时仍能安全处理(自动记录已拷贝对象)

如何选择拷贝方式?

关键看数据结构是否嵌套,以及后续是否要修改内部可变对象。

  • 纯不可变对象(如 [1, 2, 'abc'])→ 浅拷贝足够,甚至切片更轻量
  • 含嵌套列表/字典(如 {'users': [{'name': 'A'}, {'name': 'B'}]})→ 必须用 deepcopy,否则改用户信息会误影响原数据
  • 不确定结构深度或需绝对安全 → 直接用 deepcopy,避免隐性bug
  • 性能敏感且结构可控 → 浅拷贝 + 手动处理关键嵌套项(例如单独对子列表再 deepcopy)

自定义类的拷贝行为

默认情况下,copy.copycopy.deepcopy 会调用类的 __copy____deepcopy__ 方法(如果定义了)。没定义则按默认规则处理:浅拷贝新建实例并逐字段赋值;深拷贝对每个字段递归调用 deepcopy。

  • 建议:若类含可变属性(如 list/dict 类型字段),显式实现 __deepcopy__ 更可靠
  • 示例片段:
    def __deepcopy__(self, memo):
      new_obj = MyClass()
      new_obj.data = copy.deepcopy(self.data, memo) # 关键字段深拷
      return new_obj