如果您是从 C/Java/etc 中的语言开始使用 Python。家庭,它可能会帮助您停止将a
其视为“变量”,而开始将其视为“名称”。
a
, b
, 和c
不是具有相同值的不同变量;它们是相同值的不同名称。变量有类型、身份、地址和各种类似的东西。
名字没有这些。当然,值确实如此,并且您可以为相同的值有很多名称。
如果你给Notorious B.I.G.
一个热狗,*Biggie Smalls
并Chris Wallace
有一个热狗。如果将 的第一个元素更改a
为 1,则b
和的第一个元素为c
1。
如果您想知道两个名称是否命名同一个对象,请使用is
运算符:
>>> a=b=c=[0,3,5]
>>> a is b
True
然后你问:
与此有何不同?
d=e=f=3
e=4
print('f:',f)
print('e:',e)
在这里,您将 name 重新绑定e
到 value 4
。这不会以任何方式影响d
名称f
。
在您以前的版本中,您分配给a[0]
,而不是a
。因此,从 的角度来看a[0]
,您正在重新绑定a[0]
,但从 的角度来看a
,您正在就地更改它。
您可以使用该id
函数为您提供一些表示对象身份的唯一编号,以准确查看哪个对象是哪个对象,即使is
无法提供帮助:
>>> a=b=c=[0,3,5]
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261120
>>> id(b[0])
4297261120
>>> a[0] = 1
>>> id(a)
4473392520
>>> id(b)
4473392520
>>> id(a[0])
4297261216
>>> id(b[0])
4297261216
请注意,a[0]
它已从 4297261120 更改为 4297261216——它现在是不同值的名称。并且b[0]
现在也是相同新值的名称。那是因为a
并且b
仍在命名同一个对象。
在幕后,a[0]=1
实际上是调用列表对象上的一个方法。(它相当于a.__setitem__(0, 1)
.)所以,它根本没有真正重新绑定任何东西。就像打电话一样my_object.set_something(1)
。当然,对象可能正在重新绑定实例属性以实现此方法,但这不是重要的;重要的是你没有分配任何东西,你只是在改变对象。和它一样a[0]=1
。
用户570826问:
如果我们有,a = b = c = 10
这与 完全相同的情况a = b = c = [1, 2, 3]
:您有相同值的三个名称。
但在这种情况下,值是 a int
,并且int
s 是不可变的。在任何一种情况下,您都可以重新绑定a
到不同的值(例如,a = "Now I'm a string!"
),但不会影响原始值,它b
仍然c
是名称。不同之处在于,使用列表,您可以通过执行将值更改[1, 2, 3]
为[1, 2, 3, 4]
,例如a.append(4)
; 因为这实际上改变了b
和c
名称的值,所以b
现在将 b [1, 2, 3, 4]
。没有办法将值更改10
为其他任何值。10
永远是 10,就像吸血鬼克劳迪娅永远是 5(至少在她被克尔斯滕·邓斯特取代之前)。
* 警告:不要给 Notorious BIG 热狗。黑帮说唱僵尸不应该在午夜之后被喂食。