2014-05-22 181 views
2

我正在做坦克游戏,我有坦克和子弹对象。当我火,则执行下面的方法:python对象改变属性

def newshot(self,tank): 
    shot = bullet() 
    shot.loc = tank.loc 
    shot.speed = tank.direction 
    self.shots.append(shot) 

LOC是示出位置[X,Y]的列表,速度和方向都列出了显示的速度[DX,DY]。

为了移动每个子弹速度矢量被添加到它在for循环中的位置。但是每当我改变子弹的位置时,我的坦克的位置也发生了变化(我在for循环之前和之后打印出坦克位置)。 我这样做,解决了我的问题是,与其做

shot.loc = tank.loc 

我做

shot.loc = [tank.loc[0],tank.loc[1]] 

我的问题是,其中的区别?

+0

你的意思是罐跟着子弹? – vaultah

+1

您正在追加对另一个列表中的一个列表的引用。它看起来像你需要存储一份清单的副本。 – juanchopanza

+0

我解决了这个问题,但是问题出在哪里,不同之处在于shot.loc = tank.loc和shot.loc = [tank.loc [0],tank.loc [1]] –

回答

2

复制的参考,而不是价值,这意味着两个变量都在相同的对象指向。

https://docs.python.org/2/library/copy.html

在Python赋值语句不复制的对象,他们创造的目标和对象之间的绑定。对于可变项目或包含可变项目的集合,有时需要副本,以便可以更改一个副本而不更改其他副本。

tank.loc列表复制到shot.loc最简单的方法是切片的整个列表:

shot.loc = tank.loc[:] 

但见https://stackoverflow.com/a/2612815/768176其他有效的建议。

+0

最好的解决方案,最好的描述! –

1

当你使用:

shot.loc = tank.loc 

shot.loctank.loc是同一列表的引用。

要复制的列表,使用:

shot.loc = tank.loc[:] 
0

您需要deepcopy的清单。即:

import copy 
shot.loc = copy.deepcopy(tank.loc) 

这里是它如何工作的:

a = [[1, 2, 3], [4, 5, 6]] 
b = a 
a[0][1] = 10 
print a 
# [[1, 10, 3], [4, 5, 6]] 
print b # b changes too -> Not a deepcopy. 
# [[1, 10, 3], [4, 5, 6]] 


import copy 
b = copy.deepcopy(a) 
a[0][1] = 9 
print a 
#[[1, 9, 3], [4, 5, 6]] 
print b # b doesn't change -> Deep Copy 
#[[1, 10, 3], [4, 5, 6]]