Python具有引用 对象的 名称 。对象与名称分开存在,名称与它们引用的对象分开存在。 __
# name aa = 1337 # object 1337
在为“名称分配名称”时,右侧 评估 所引用的对象。类似于如何
2 + 2评估
4,
a评估原始
1337。
# name bb = a # object referred to by a -> 1337
在这一点上,我们有
a -> 1337和
b -> 1337-注意,无论名字知道对方!如果我们测试
a is b,则两个名称都被 评估
为同一个对象,这显然相等。
重新分配名称只会更改该名称所指的内容-也没有可以更改其他名称的连接。
# name a - reassigna = 9001 # object 9001
此时,我们有
a -> 9001和
b -> 1337。如果我们现在测试
a is b,则两个名称将被 评估 为不同的不同对象。
如果您来自诸如C之类的语言,那么您将习惯于 包含 值的变量。例如,
char a =12可以读取为“
a是包含
12”的存储区域。最重要的是,您可以让多个变量使用相同的内存。将另一个值分配给变量会更改共享内存的内容,因此也会更改两个变量的值。
+- char a -+| 12 |+--char b -+# a = -128+- char a -+| -128 |+--char b -+
这不是Python的工作方式:名称不包含任何内容,而是引用单独的值。例如,
a =12可以读取为“
a是指值的名称
12”。最重要的是,您可以有多个名称引用相同的值-
但它仍将是单独的名称,每个名称都有其自己的引用。为名称分配另一个值会更改该名称的引用-但不会影响其他名称的引用。
+- name a -+ - --> +- <12> ---+ / | 12 |+- name b -+ -/ +----------+# a = -128 +- <-128> -++- name a -+ -----> | -128 | +----------+ +- <12> ---++- name b -+ -----> | 12 | +----------+
令人困惑的一点是, 可变 对象似乎违反了名称和对象的分隔。通常,这些是容器(例如
list,
dict…),并且类在默认情况下表现出相同的行为。
# name mm = [1337] # object [1337]# name nn = m # object referred to by m
与普通整数类似,包含整数
1337的列表
[1337]是 一个 可以由多个独立名称引用 的对象 。如上所述,
n ism评估为
True且
m = [9001]不变
n。
但是,对名称的某些操作会更改名称 和所有别名所 看到的值。
# inplace add to mm += [9001]
此操作之后,
m == [1337, 9001]并
n is m仍然适用。实际上,by
n所看到的值也已更改为
[1337,9001]。这似乎违反了上述行为,在别名中,别名互不影响。
这是因为
m += [9001]没有更改
m所指的内容。它仅更改引用的列表(和别名)的 内容 。双方并仍然指向原始列表对象,它的 值
被改变。
m``n``m``n__
+- name m -+ - --> +- […] -+ +--- <@0> -+ / | @0 | -> | 1337 |+- name n -+ -/ +-------+ +----------+# m += [9001]+- name m -+ - --> +- […] -+ +--- <@0> -++--- <@1> -+ / | @0 @1 | -> | 1337 || 9001 |+- name n -+ -/ +-------+ +----------++----------+



