首页 > 解决方案 > 赋值运算符和变量标识符

问题描述

以下代码 (python3) 打印 5 而不是 4。

x = 5
y = x
x = 4
print(y)

但是现在我发现一种相反的行为发生的情况,其中一个变量被分配到内存中的某个位置,而不是存储在那里的值。有几次我在我的代码中发现了一个错误,因为这样的事情。

是否存在与上述代码(以及在 Python 中)类似的情况,其中初学者可能打算让代码将一个变量的当前值存储在一个新变量中,而不是它分配标识符的值?另外,我并不是要在这里用“值”和“变量”这两个词强加任何特定的数据类型,所以如果这些术语不正确,我深表歉意。

如果有一些关于这种行为在某些常见语言(尤其是 python、javascript、java、c、haskell)上的变化的评论,我很想听听。当然,任何关于这个问题的适当术语(以及如何标记它)的建议也将不胜感激。


编辑:我正在接受一个描述行为如何随不可变/可变类型变化的答案,因为这可能是我遇到的行为,并且我特别询问了初学者程序员的混淆来源。但是,访问此页面并有类似问题的人也应该参考评论部分,这表明一般答案不像可变/不可变数据类型那么简单。

标签: python

解决方案


>>> 1
1
>>> id(1)
140413541333480
>>> x = 1
>>> id(x)
140413541333480
>>> z = 1
>>> id(z)
140413541333480
>>> y = x
>>> id(y)
140413541333480
>>>

出于优化的目的,只有 1 的单个副本,并且所有变量都引用它。

现在,python 中的整数和字符串是不可变的。每次定义一个新的时,都会生成一个新的参考/ID。

>>> x = 1 # x points to reference (id) of 1
>>> y = x # now y points to reference (id) of 1
>>> x = 5 # x now points to a new reference: id(5)
>>> y     # y still points to the reference of 1
1
>>> x = "foo" 
>>> y = x
>>> x = "bar"
>>> y
'foo'
>>> 

列表、字典是可变的,即您可以在同一引用处修改值。

>>> x = [1, 'foo']
>>> id(x)
4493994032
>>> x.append('bar')
>>> x
[1, 'foo', 'bar']
>>> id(x)
4493994032
>>>

因此,如果您的变量指向一个引用并且该引用包含一个可变值并且该值已更新,则该变量将反映最新值。

如果引用被覆盖,它将指向引用所指向的任何内容。

>>> x = [1, 'foo']
>>> y = x  # y points to reference of [1, 'foo'] 
>>> x = [1, 'foo', 'bar'] # reference is overridden. x points to reference of [1, 'foo', 'bar']. This is a new reference. In memory, we now have [1, 'foo'] and [1, 'foo', 'bar'] at two different locations. 
>>> y
[1, 'foo']
>>>

>>> x = [1, 'foo']
>>> y = x
>>> x.append(10) # reference is updated
>>> y
[1, 'foo', 10]
>>> x = {'foo': 10}
>>> y = x
>>> x = {'foo': 20, 'bar': 20}
>>> y
{'foo': 10}
>>> x = {'foo': 10}
>>> y = x
>>> x['bar'] = 20 # reference is updated
>>> y
{'foo': 10, 'bar': 20}
>>>

您的问题的第二部分(通用语言)太宽泛了,Stackoverflow 不是解决这个问题的正确论坛。请对您感兴趣的语言进行研究 - 每个语言组及其论坛都有大量可用信息。


推荐阅读