赋值运算符和变量标识符



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

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

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

是否存在与上述代码(以及Python中)类似的情况,初学者可能希望代码将一个变量的当前值存储在一个新变量中,但不是它分配给标识符的值?此外,我无意在这里用"值"one_answers"变量"来强加任何特定的数据类型,因此,如果这些术语不正确,我深表歉意。

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


EDIT:我接受一个描述行为如何随不可变/可变类型而变化的答案,因为这可能是我遇到的行为,我特别询问了初学者的困惑来源。然而,如果有人访问此页面时提出了类似的问题,也应该参阅注释部分,该部分表明一般答案并不像可变/不可变数据类型那么简单。

>>> 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'
>>> 

列表、dict是可变的,也就是说,您可以在同一引用处修改值。

>>> 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不是合适的论坛。请对你感兴趣的语言进行研究——每个语言组和论坛上都有大量信息。

您的解决方案在本视频中。。。从这个视频中,你可以很好地理解它。所以请仔细观看。。。

https://www.youtube.com/watch?v=_AEJHKGk9ns

与其他语言不同,python不会复制对象并将其分配给新变量,即在您的情况下y=x

python在这里实际做的是将y的引用指向存储在x 中的值对象

让我们用你的例子更清楚

x=5

在执行该行之后,x将引用存储器中存储值5 的对象

y = x

现在,x和y都将引用值5。

x=4

python的魔力从这一行开始,请记住,这里x和y是不可变的对象,这意味着它们的值不能更改,但当你将4分配给x时,它只是在内存中创建一个包含4的新块,x现在将引用该块,然而,y仍然引用值为5的旧块。所以输出将是5

如果是像列表这样的可变对象,如果你这样做

x = [5, 6]
y = x
x.append(7)
print(y)

这将打印

[5,6,7]

作为输出

x = 5   
id(x) = 94516543976904     // Here it will create a new object
y = x    
id(y) = 94516543976904    // Here it will not create a new object instead it will refer to x (because both of them have same values).
x = 4
id(x) = 94516543976928    // Here we are changing the value of x. A new object will be created because integer are immutable.

最新更新