Python副作用我不明白

时间:2012-03-16 07:57:02

标签: python side-effects

def group_move(group, damper):
    # Make a copy to test values
    new = group

    # See what the original group value is
    print("Test = " + str(group.ctris[0].p1.x))
    dr = some float
    dx = some float
    dy = some float
    # Make changes to new
    moveGroup(new, dr, dx, dy)
    # See if those changes produce allowed values
    if (off_board_check(new) == 1):
        damper += 2.0
        # Reset to original to try again
        print("Test Here = " + str(group.ctris[0].p1.x))
        group_move(group, damper)
    else:
        # If everything is on the board, then make the change
        group = new

如果我运行它,我会在第一次递归时看到Test打印行与Test Here打印行产生不同的值。为什么?这段代码如何影响group的值?在测试值失败的情况下,我试图将未更改的group传递到group_move的下一个递归级别,但似乎{I}在某种程度上受到影响甚至在我做任何事情之前递归调用。上面的内容有何不同:

group

3 个答案:

答案 0 :(得分:6)

# Make a copy to test values
new = group

评论不正确。那不是复制品。所有这一切都是使一个名为new的变量指向group所指向的同一对象。

如果您想创建实际副本,可能需要查看copy.deepcopy()

答案 1 :(得分:2)

当你这样做时

# Make a copy to test values
new = group

您正在复制对象

参考

此外,你的考试不是一个聪明的"一个是因为,在您的示例中,您使用基本类型变量而不是对象

作为一般规则记住

  

Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。 对于可变或包含可变项目的集合,有时需要副本,因此可以更改一个副本而不更改另一个副本。该模块提供了通用的浅层和深层复制操作(如下所述)。

来自here

答案 2 :(得分:0)

new = group

这意味着“new应该是评估表达式group的结果的名称(即,当前由group命名的事物,因为表达式只是一个名称)” 。这是别名,而不是副本。

x = 1
y = x
x = 7
y = 77

这里也是一样的。 x = 1; y = x导致它们都引用表示整数1的对象。 x = 7导致x停止引用1对象并开始引用表示整数7的另一个对象。同样适用于y = 77。独立性不是因为任何复制(因为没有任何复制),而是因为代码中没有任何内容指定对引用对象的更改(实际上这对于{{ 1)}在Python中)。当人们期望这段代码最终以x等于77结尾时,它们实际上是在解释不一致的东西,期望某些行上的值语义和其他行上的引用语义。 值语义和引用语义都预测实际结果