python对象改变属性

时间:2014-05-22 05:24:31

标签: python list oop

我正在进行坦克游戏,我有坦克和子弹物。当我开火时,执行以下方法:

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

我的问题是区别在哪里?

3 个答案:

答案 0 :(得分:2)

您复制了引用而不是值,这意味着两个变量指向同一个对象。

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

  

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

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

shot.loc = tank.loc[:]

但请参阅https://stackoverflow.com/a/2612815/768176了解其他有效建议。

答案 1 :(得分:1)

使用时:

shot.loc = tank.loc

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

要复制列表,请使用:

shot.loc = tank.loc[:]

答案 2 :(得分: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]]