以下示例:
a = 1
b = a
b = 3
print(a) # gives 1
但是,当我这样做时:
a = [1,2]
b = a
b[0] = 3
print(a) # gives [3,2]
我如何知道变量是被视为(C ++类型)引用还是普通变量?基本数据类型只是“一切都是参考”规则的例外吗?我遗漏了潜在机制的哪些细节?
答案 0 :(得分:3)
Python中的所有变量都是引用。基本数据类型不是例外。
在第一个示例中,您重新分配 b
。它不再引用与a
相同的对象。
在第二个示例中,您修改 b
。由于您之前已将a
和b
设置为对同一对象的引用,因此该修改也适用于a
。
答案 1 :(得分:1)
为了更好地掌握这类问题,我建议您使用在线Python导师。这是一个非常方便的工具,可以在代码逐步执行时呈现内存中对象的图形表示。
为了展示在线Python Tutor的实际应用,我将玩具示例拆分为小片段,然后捕获相应的屏幕截图。希望这可以帮助您弄清楚Python引用的工作原理。
a = 1
b = a
b = 2
x = [a, b]
y = x
y[1] = 3
如果您想使用此代码,请按this link。
答案 2 :(得分:0)
每个名字都是一个简单的参考。
变量名是对象的引用,重要的是对象的属性。规则:数字(int,float等),字符串,元组(和其他)是不可变的 - 只读。列表,词典,集合(和其他)是可变的。
所以您观察到的差异是因为int是不可变的 - 它们无法更改。列表是可变的 - 它们可以更改。
在两种情况下分配a = b
都会复制引用。当您重新分配b
时会发生这种情况,在这种情况下,左侧引用了一个新对象。对于可变对象,引用的对象会发生更改,使用哪个引用无关紧要。
答案 3 :(得分:0)
一切都是参考。所有python变量都引用对象,所有对象都可以有多个引用。
您所看到的差异在于赋值运算符和__setitem__
运算符之间。语法类似,但它们做了不同的事情。
这是一个赋值,它更新了变量var
的引用。
var = 'something'
这使用setitem,它实际上是对左侧对象的方法调用。
obj[i] = 'thing'
# is the same as
obj.__setitem__(i, 'thing')
__setitem__
的作用取决于类型,但通常会修改obj
。从这个意义上说,b[0] = 3
比b.append(3)
更像b = 3
。不可变类型没有setitem方法,并在setitem运算符上抛出错误。