赋值运算符和变量标识符

时间:2019-02-01 03:27:14

标签: python

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

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

但是我时不时地发现一种相反的情况发生,将变量分配给内存中的某个位置,而不是存储在其中的值。几次,由于这种原因,我在代码中发现了一个错误。

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

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


编辑:我正在接受一个答案,该答案描述了行为如何随不可变/可变类型而变化,因为这很可能是我遇到的行为,我特别询问了初学者程序员的困惑根源。但是,访问此页面时遇到类似问题的人也应参考注释部分,该部分指示一般性回答并不像可变/不可变数据类型那么简单。

3 个答案:

答案 0 :(得分:2)

>>> 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并不是解决该问题的合适论坛。请对您感兴趣的语言进行研究-每个语言​​组及其论坛上都有大量可用信息。

答案 1 :(得分:0)

您的解决方案在此视频中...从此视频中,您可以正确理解它。 所以请仔细观看...

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]

作为输出

答案 2 :(得分:0)

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.