按值传递可变对象

Posted

技术标签:

【中文标题】按值传递可变对象【英文标题】:Pass mutable object by value 【发布时间】:2018-07-20 08:45:25 【问题描述】:

我在 for 循环中更改状态字典,并在每次迭代时将新状态附加到列表中。

在 Python 中,字典当然是可变的,所以添加到列表中的是对不断变化的字典对象的引用。所以最后我只得到一个相同重复引用的列表,指向状态的最终版本。

state = 'temp': 21.6, 'wind': 44.0
state_list = []
for i in range(10):
    state['temp'] += 0.5
    state['wind'] -= 0.5
    state_list.append(state)

有没有办法告诉解释器我希望“按值传递”?我能够从追加前的行中的状态构造一个元组或可变的东西,并用说元组附加列表。我只想检查这是最好的解决方案。

【问题讨论】:

没有。您必须明确复制。 “所以最后我只是得到一个相同重复引用的列表,指向状态的最终版本”实际上,列表中的所有元素 都是 相同 dict,句号。 【参考方案1】:

它不是“按值传递”,因为列表实际上包含对对象的引用。 您需要创建copy 并附加到列表中,即:

state_list.append(state.copy())

请注意,.copy 创建了对象的浅表副本。对于容器,这意味着 container 是新的,但它会保存相同的引用。由于您的状态由浮点数描述,并且浮点数是不可变的,因此这不会导致任何问题。

如果您需要复制包含可变对象的容器并同时复制这些对象,您可以使用deepcopy

【讨论】:

以防字典对象是 OP 实际操作的简化表示,值得注意的是 copydeepcopy 之间的区别:docs.python.org/2/library/copy.html

以上是关于按值传递可变对象的主要内容,如果未能解决你的问题,请参考以下文章

不可变且按值传递

对 Java 的按值传递和不变性感到困惑

python中的引用传递,可变对象,不可变对象,list注意点

第四章 对象与类

python 函数传递可变不可变对象

python—可变对象与不可变对象 参数传递