What is the name of what the list is doing to the variable x to prevent it from being bound to any changes to the original value of x? Shielding? Shared structure? List binding? Nothing is coming back from a Google search using those terms.
因为list没有做任何事情,也不是集合的属性。在
在Python中,变量是名称。在
>>> x = 5
这意味着:x应该是值5的名称。在
^{pr2}$
这意味着:l应该是由x命名的值(5)并使用该值([5])生成的一个元素列表所产生的值的名称。在
>>> x += 1
x += 1在这里被重写成x = x + 1,因为整数是不可变的。不能使值5增加1,因为这样它将继续是5。在
我称之为包含对象的“不变性”。在
我想你可以把你的情况和下面的情况比较一下:
区别在于:
在这种情况下(可变的情况),您可以对列表
l
中包含的原始对象x
进行变异。在但是,在您的情况下,
x
指向一个不可变的对象(5
),然后将其添加到列表中。{{cd5>之后不仅仅是对这个列表的引用。在因此
x += <something>
要么修改x
,要么根据对象类型的性质用另一个对象替换它。在编辑:这也与列表的性质无关。你可以用两个变量实现同样的效果:
^{pr2}$对比
由于}引用的对象的标识保持不变。在
int
的不变性,第一个将改变x
,导致x is y
为false;而在第二个示例中,x is y
保持为真,因为对象(列表)发生了变化,x
和{因为list没有做任何事情,也不是集合的属性。在
在Python中,变量是名称。在
这意味着:
^{pr2}$x
应该是值5
的名称。在这意味着:
l
应该是由x
命名的值(5
)并使用该值([5]
)生成的一个元素列表所产生的值的名称。在x += 1
在这里被重写成x = x + 1
,因为整数是不可变的。不能使值5
增加1,因为这样它将继续是5
。在因此,这意味着:
x
将不再是它当前名称的名称,而是开始成为数学表达式x + 1
产生的值的名称。一、 例如,6
。在引用语义就是这样发生的。没有理由期望清单的内容会发生变化。在
现在,让我们来看看值语义会发生什么,在一种类似Python的假设语言中,变量的处理方式与在C中处理变量的方式相同
这意味着:
^{pr2}$x
是内存块的一个标签,它包含一个数字5
的表示形式。在这意味着:
l
是一个内存块的标签,该内存块包含一些列表结构(可能包括一些指针等),它将以某种方式初始化,以便它表示一个包含1个元素的列表,该元素的值为5
(从x
变量复制)。它不能在逻辑上包含x
,因为这是一个单独的变量,我们有值语义;所以我们存储一个副本。在这意味着:增加
x
变量中的数字;现在它是6
。同样,这个列表是不受影响的。在不管您的语义如何,您都不能这样影响列表内容。期望列表内容发生变化意味着您的解释不一致。(如果您将代码重写为
l = [5]; x = l[0]; x += 1
,这一点就更加明显了。)您所描述的行为与引用有关。如果您熟悉
c
,那么您可能也熟悉“指针”。c
中的指针可能会变得非常复杂,而Python使用的数据模型可以大大简化事情。但是在c
中有一点背景知识有助于理解Python在这里的行为,这与c
指针的行为密切相关。所以“指针”、“引用”和“取消引用”都是与您所谈论的内容相关的术语,尽管它们都不是它的“名称”。也许它最好的名字是“间接寻址”——尽管这有点过于抽象和包容;这是一种非常特殊的间接寻址。也许是“参考语义学”?这里有一个来自GvR自己的演讲中的slide使用了这个术语,google search显示了一些有用的点击率。在但如果你在
c
没有任何背景知识,这里是我最好的解释。简而言之,可以将Python名称看作指向对象的指针。所以当你给一个值指定一个名字时,你就是在“指向”这个值。然后,当您为名称指定一个新值时,您将它指向一个新值;但是旧值不会因此而发生任何更改。在这里将名称看作指针时,这似乎很自然;“名称的值”已更改,但“值的值”没有更改。在有点困惑的是
+=
的行为不一致。当你在一个数字上使用+=
时,使用上面的比喻,结果就非常有意义了:其行为与您所做的
x = x + 1
完全相同。在但有时{}以一种发生原位突变的方式过载。一个稍微不一致的成语:
^{pr2}$所以这里,值的值改变了。这实际上不是我最喜欢的Python,但有很好的理由。在
相关问题 更多 >
编程相关推荐