Python copy.deepcopy()函数不正常工作

5 投票
3 回答
18119 浏览
提问于 2025-04-17 20:20

我最近在玩深拷贝和浅拷贝这两个功能,但发现它们都有同样的问题。感觉复制的结果像是一个引用(或者说指针),而不是一个真正的复制。我在用Python处理数据记录(类),可能这就是问题所在。我给你举个例子:

>>> import copy
>>> class player1:
...    age = 23
...    score = 1
>>> class player2:
...    age = 14
...    score = 2
>>> player3 = copy.deepcopy(player1)

我打印了一些参数。

>>> print player1.age, player1.score
23 1
>>> print player2.age, player2.score
14 2
>>> print player3.age, player3.score
23 1

现在我在player1的数据记录中增加了分数参数。

>>> player1.score += 3

然后我又打印了一次结果。

>>> print player1.age, player1.score
23 4
>>> print player2.age, player2.score
14 2
>>> print player3.age, player3.score
23 4 

为什么player3的值也变了? 我只是增加了player1的一个参数,并没有动到player3。这个数据是可变的,而不是不可变的。

提前谢谢你。

3 个回答

2

来自文档(我强调的部分):

这个版本不会复制像模块、、函数、方法这样的类型,也不会复制堆栈跟踪、堆栈帧、文件、套接字、窗口、数组或任何类似的类型。

你正在尝试复制类,所以:

>>> player3 = copy.deepcopy(player1)
>>> player1 is player3
True

但是

>>> p1 = player1()
>>> p2 = player2()
>>> p3 = copy.deepcopy(p1)
>>> p1 is p3
False
3

这就是按照设计来工作的。

在你的示例代码中,你复制的是类的定义,而不是对象的实例。从 copy 模块的手册页面来看:

It does “copy” functions and classes (shallow and deeply), by returning the original object
unchanged

所以:

player3 = copy.deepcopy(player1)

这和下面的内容是一样的:

player3 = player1

不过,如果你复制的是类的实例,那你就会得到预期的结果:

player3 = copy.deepcopy(player1())
10

问题在于,你实际上是在复制类的定义,而不是类的一个实例。

代码的另一个问题是,属性 agescore 是类的一部分,这意味着所有这个类的实例都会共享这些属性。这可能不是你想要的结果。

你可能想要做的是:

import copy
class Player:
    def __init__(self, age, score):
        self.age = age
        self.score = score

player1 = Player(23, 1)
player2 = Player(14, 2)
player3 = copy.deepcopy(player1)

player1.age += 1

print "player1.age", player1.age
print "player3.age", player3.age

这样做会得到你期望的结果:

player1.age 24
player3.age 23

撰写回答