以下代码(python3)打印5而不是4。
x = 5
y = x
x = 4
print(y)
但是我时不时地发现一种相反的情况发生,将变量分配给内存中的某个位置,而不是存储在其中的值。几次,由于这种原因,我在代码中发现了一个错误。
是否存在与上述代码(和Python)类似的情况,在这种情况下,初学者可能打算让代码将一个变量的当前值存储在新变量中,但它会代替标识符来分配值?另外,我的意思并不是要在此处用“值”和“变量”一词来强加任何特定的数据类型,因此,如果这些术语不正确,我深表歉意。
如果有关于此行为在某些常见语言(尤其是python,javascript,java,c,haskell)上如何变化的评论,我很想听听。 ,对于此问题的合适术语(以及如何标记)的任何建议也将不胜感激。
编辑:我正在接受一个答案,该答案描述了行为如何随不可变/可变类型而变化,因为这很可能是我遇到的行为,我特别询问了初学者程序员的困惑根源。但是,访问此页面时遇到类似问题的人也应参考注释部分,该部分指示一般性回答并不像可变/不可变数据类型那么简单。
答案 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.