【发布时间】:2021-02-11 10:42:21
【问题描述】:
在调试一段代码时遇到了这个问题。如果之前没有意识到这种行为。
foo = bar = [1, 2, 3]
hex(id(foo))
Out[121]: '0x1f315dafe48'
hex(id(bar))
Out[122]: '0x1f315dafe48'
两个“变量”都指向同一个内存位置。但是现在如果一个改变了,另一个也会改变:
foo.append(4)
bar
Out[126]: [1, 2, 3, 4]
所以基本上在这里我们有两个名称分配给同一个变量/内存地址。这不同于:
foo = [1, 2, 3]
bar = [1, 2 ,3]
hex(id(foo))
Out[129]: '0x1f315198448'
hex(id(bar))
Out[130]: '0x1f319567dc8'
这里对foo 或bar 的更改不会对另一个产生任何影响。
所以我的问题是:为什么这个特性(可变类型的链式赋值)甚至存在于 Python 中?除了给你工具让你在脚上开枪之外,它还有其他用途吗?
【问题讨论】:
-
foo = bar = [1, 2, 3]的行为与bar = [1, 2, 3]后跟foo = bar的行为一致。 -
@MarkMeyer,同意。但是你为什么要知道对 foo 的任何更改也会更改 bar 呢?将两个名称分配给同一个变量有什么意义?
-
我不知道。我很确定我从未在现实生活中使用过这种分配模式。另一方面,我真的不希望我的代码在没有明确制作副本的情况下分配(可能)大型集合。
-
如果你调用
list.sort(foo),你宁愿希望list.sort函数持有与foo相同的列表的引用,而不是它的副本;否则它将对自己的副本进行排序,foo保持不变。但当然list.sort中必须有一个局部变量,它是一个不同于foo的变量(它可能被称为self)。因此,您希望两个不同的变量引用同一个可变对象的原因有很多。