Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Copy (拷贝)

🚀 1. copy 与 deepcopy 是什么?

来自模块:

import copy

Python 有两种复制方式:

方式 含义
copy.copy() 浅拷贝(shallow copy)
copy.deepcopy() 深拷贝(deep copy)

🟥 2. 浅拷贝(copy)是什么?

浅拷贝只会复制 最外层对象,内部对象只是引用。

等价于:

  • 外层复制 ✅
  • 内层共享 ❌(仍指向原对象)

例如:

import copy

a = [1, [2, 3]]
b = copy.copy(a)

结构示意:

a ------> [1,  [2,3]]
b ------> [1,  ┘]

修改 b 的内部列表:

b[1].append(4)
print(a)

输出:

[1, [2, 3, 4]]

浅拷贝 -> 内部结构共享。

🟦 3. 深拷贝(deepcopy)是什么?

深拷贝会递归复制所有子对象:

  • 外层复制 ✅
  • 内层也复制 ✅
  • 完全独立的结构 👍
import copy

a = [1, [2, 3]]
b = copy.deepcopy(a)
b[1].append(4)

print(a)

输出:

[1, [2, 3]]

完全不会影响原对象。

🟩 4. 本质差异(最重要)

行为 copy(浅拷贝) deepcopy(深拷贝)
外层对象复制
内层对象复制 ❌(共享引用) ✅(递归复制)
修改内层是否影响原对象
速度
内存消耗

🟧 5. 常见使用场景

copy(浅拷贝)适合:

  • 内部结构不会修改
  • 只想复制“外壳”
  • list / dict 需要快速复制
  • 数据对象很大,不想深度复制

示例:

new_list = old_list.copy()

deepcopy 适合:

  • 复杂嵌套结构
  • 想得到完全独立副本
  • 配置复制、对象克隆
  • 避免多层 list/dict 互相影响

示例:

new_dict = copy.deepcopy(config_dict)

🟫 6. 深拷贝的危险点:循环引用

深拷贝会自动处理循环引用:

a = []
a.append(a)

import copy
b = copy.deepcopy(a)

不会死循环。

🟪 7. 某些对象永远不会 deep copy

例如:

  • file 文件句柄
  • socket
  • 线程对象
  • 协程对象
  • 内置类对象(如 range、iterator)

这些对象会被原样引用(因为无法克隆)。

🟨 8. 自定义类如何控制 copy 行为?

你可以定义:

def __copy__(self):
    ...

def __deepcopy__(self, memo):
    ...

示例:

class A:
    def __init__(self, x):
        self.x = x
    
    def __deepcopy__(self, memo):
        print("doing deepcopy")
        return A(copy.deepcopy(self.x, memo))

⭐ 9. 最佳实践总结(非常重要)

想要复制一个 dict/list,但不修改内部 -> 用 copy()

b = a.copy()

需要完全独立拷贝(例如配置)-> 用 deepcopy()

b = copy.deepcopy(a)

尽量避免随意 deepcopy:成本高

常用替代方案:

① JSON 序列化(简单嵌套结构)

import json
b = json.loads(json.dumps(a))

② 手动复制你需要的字段

更可控、更高效。

🔥 10. 一屏速查表(你可以直接收藏)

copy.copy(x):

  • 浅拷贝,只复制最外层
  • 内部对象保持引用
  • 快、轻量

copy.deepcopy(x):

  • 深拷贝,递归复制全部对象
  • 完全独立,互不影响
  • 慢、消耗内存多
  • 自动处理循环引用