python基础-类的浅拷贝和深拷贝

Python变量赋值与拷贝:赋值操作使变量指向同一对象,修改影响所有引用;浅拷贝复制顶层对象,子对象共享,修改子对象影响原对象;深拷贝递归复制所有对象,源对象与拷贝对象完全独立,互不影响

Posted by Hilda on July 9, 2025

1.变量的赋值操作

只是形成两个变量,实际上还是指向同一个对象

【1】在Python中,当你执行赋值操作,例如 a = [1, 2, 3] 然后 b = a,你并没有创建两个独立的对象。实际上,变量 ab 都指向了内存中的同一个列表对象 [1, 2, 3]

1
2
3
4
a = [1, 2, 3]
b = a
print(a, id(a))
print(b, id(b))

image-20250709141116624

【2】修改其中一个变量: 如果你通过 b 修改了列表,你会发现 a 也会受到影响,因为它们引用的是同一个底层数据。

1
2
3
4
5
6
7
a = [1, 2, 3]
b = a
print(a, id(a))
print(b, id(b))
b[0] = 100
print(a)
print(b)

image-20250709141204426

2.浅拷贝(只拷贝顶层对象,子对象共享)

Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象

浅拷贝创建一个新对象,但新对象中包含的子对象(如果存在的话)仍然是原始对象的引用。这意味着,如果你修改了子对象,原始对象和拷贝对象都会受到影响。

在Python中,实现浅拷贝有几种常见的方法:

【1】切片操作 [:] 对于列表、元组等序列类型,使用切片 [:] 可以创建一个浅拷贝。

1
2
3
4
5
6
7
8
9
10
original_list = [[1, 2], 3]
shallow_copied_list = original_list[:] # 切片实现浅拷贝
print(id(original_list))
print(id(shallow_copied_list))
print(id(original_list[0]))
print(id(shallow_copied_list[0]))  # 子对象共享
# 修改子列表
shallow_copied_list[0].append(90)
print(original_list)
print(shallow_copied_list)

image-20250709141621323

【2】list() 构造函数: 使用 list() 构造函数也可以创建一个列表的浅拷贝。

1
2
3
4
5
6
print("\n", "-"*40, "\n")
l1 = [["Hello"], "World"]
l2 = list(l1)
print(l1, l2)
print(id(l1), id(l2))
print(id(l1[0]), id(l2[0]))

image-20250709141907355

【3】copy() 模块的 copy() 函数: 对于更复杂的对象,可以使用 copy 模块的 copy() 函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class CPU:
    pass

class Disk:
    pass

class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk

import copy
c1 = Computer(CPU(), Disk())
print(c1, id(c1), id(c1.cpu), id(c1.disk))
c2 = copy.copy(c1)
print(c2, id(c2), id(c2.cpu), id(c2.disk))

image-20250709142222984

3.深拷贝

使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CPU:
    pass

class Disk:
    pass

class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk

import copy

c1 = Computer(CPU(), Disk())
print(c1, id(c1), id(c1.cpu), id(c1.disk))
c2 = copy.deepcopy(c1)
print(c2, id(c2), id(c2.cpu), id(c2.disk))

image-20250709142320047