【问题标题】:Python: variable changes without being called [duplicate]Python:变量更改而不被调用[重复]
【发布时间】:2019-01-01 06:50:03
【问题描述】:

我对将类变量存储在第二个变量中以供以后调用存在疑问。 这是我的代码(简化为可读):

class Agent(object):
    def __init__(self):
        self.actual = []

class Play(object):

    def __init__(self):
        self.x = 0.45 * 400
        self.y = 0.5 * 400
        self.position = []
        self.position.append([self.x, self.y])
        self.x_change = 20
        self.y_change = 0

    def do_move(self, move, x, y):
        move_array = [self.x_change, self.y_change]

        if move == 1 and self.x_change == 0:  # right
            move_array = [20, 0]
        self.x_change, self.y_change = move_array
        self.x = x + self.x_change
        self.y = y + self.y_change

        self.update_position(self.x, self.y)

    def update_position(self, x, y):
        self.position[-1][0] = x
        self.position[-1][1] = y


def run():
    agent = Agent()
    player1 = Play()
    agent.actual = [player1.position]
    print(agent.actual[0])
    i = 1
    player1.do_move(i, player1.x, player1.y)
    print(agent.actual[0])

run()

>> [[180.0, 200.0]]
>> [[200.0, 200.0]]

这是我无法理解的。为什么,如果agent.actual存储了player.position,在agent.actual = [player1.position]之后没有修改,它的值实际上在两个print()之间变化? 我修改了player.position,但没有修改agent.actual,这意味着它应该保持不变。我想不通!

编辑: 按照建议,我尝试了以下方法:

agent.actual = player1.position.copy()

agent.actual = player1.position[:]

agent.actual= list(player1.position)

import copy
agent.actual = copy.copy(player1.position)

agent.actual = copy.deepcopy(player1.position)

所有这些方法总是像以前一样返回两个不同的值:

>> [[180.0, 200.0]]
>> [[200.0, 200.0]]

【问题讨论】:

  • agent.actual 是一个列表,其中包含另一个列表的引用,该列表是可变的。因此,对player1.position 的更改会反映在agent.actual 中。如果您不想要这种行为,请参阅副本以了解如何创建副本。
  • 谢谢,终于明白了。很抱歉重复,我这样做是因为我不知道 Python 会参考而不是复制,而不是因为我没有准确地查找它。
  • @jonrsharpe 我按照您提到的问题中的建议进行了尝试,但是正如您在我的编辑中看到的那样,结果并没有什么不同。

标签: python python-3.x class oop methods


【解决方案1】:

Player.position 是列表,表示它是可变类型。如果将此列表放在另一个列表中,Python 会引用它,而不是复制。

当您在列表中添加/删除/更改项目时,它会在引用所在的所有位置更改。

分配给agent.actual 时需要复制一份。查看 Python 中的 copy 模块或重构代码(提示:tuple 是不可变类型)

【讨论】:

  • 谢谢,正如您在我的编辑中看到的那样,我尝试了您对 copy 模块的建议,但它不起作用。
  • @MauroComi 不在列表中持有位置,使用元组。复制列表会在极端情况下造成麻烦。元组是不可变的。
猜你喜欢
  • 1970-01-01
  • 2018-01-26
  • 2018-11-01
  • 2013-07-15
  • 1970-01-01
  • 2011-12-16
相关资源
最近更新 更多