2014-02-27 115 views
2

我一直在玩deepcopy函数和复制函数,并且我得到了与它们相同的问题。这就像复制是一个引用(或指针)而不是正确的副本。我在Python与数据记录(类)的工作,也许它可能是..我告诉你一个例子:Python copy.deepcopy()函数无法正常工作

>>> 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 

为什么玩家3变了? 我刚刚在player1中增加了一个参数,而不是player3。它是可变的而不是不可变的。

在此先感谢。

回答

3

documentation(重点煤矿):

此版本不复制类型,如模块,,函数,方法, 也不栈跟踪,堆栈帧,也不文件,插座,窗口,也不是数组,也不是任何类似的类型。

你试图复制类等:

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

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

这是事先设计好的。

在您的示例代码中,您正在复制类定义,而不是对象实例。从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()) 
4

问题是您实际上正在复制类定义而不是类的实例。

该代码的另一个问题是属性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 
+0

我不同意,年龄和评分进行类属性的事实负责观察到的行为;如果player3真的是一个不同的课程,OP将不会有这个问题。我同意他们*应该*是实例属性,但这是不同的。 – DSM

+0

@DSM:是的,同意了。起初我一直沉迷于此,甚至没有看到根本没有阶级实例。我纠正了这一点。 –