关于python:共享引用和等式

Shared References and Equality

使用python 3.4并通过O'reily的书中的示例进行工作。示例显示:

1
2
3
A = ['spam']
B = A
B[0] = 'shrubbery'

运行print A后的结果:

1
'shrubbery'

现在我的思维过程是,A被定义了,但从未改变。

这个例子产生了不同的结果

1
2
3
A = 'string'
B = A
B = 'dog'

这是运行print A后的结果:

1
'string'

有人能解释吗?


在第一个示例中,您正在修改B引用的列表。

做:

1
B[0] = 'shrubbery'

告诉python将B引用的列表中的第一项设置为'shrubbery'的值。此外,这个列表恰好与A引用的列表相同。这是因为这样做:

1
B = A

使BA分别引用同一列表:

1
2
3
4
5
>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>

因此,对B引用的列表的任何更改也会影响A引用的列表(反之亦然),因为它们是同一对象。

但是,第二个示例不修改任何内容。相反,它只是将名称B重新分配给一个新值。

执行此行后:

1
B = 'dog'

B不再引用字符串'string',而是引用新字符串'dog'。同时,A的值保持不变。


与大多数现代动态语言一样,Python中的变量实际上是引用,类似于C指针。这意味着,当您执行类似于A = B的操作时(其中a和b都是变量),只需指向内存中与b相同的位置。

在第一个示例中,您正在改变(修改)现有的对象——这就是variable_name[index/key] = value语法所做的。A和B继续指向同一个东西,但这个东西的第一个条目现在是"灌木",而不是"垃圾邮件"。

在第二个例子中,当你说B = 'dog'时,你使b指向一个不同的(此时是新的)对象。


enter image description here

我希望你能这样理解它:—)

正如您在第一种方法中看到的,它们都引用相同的list,第二种方法不同,所以第二种方法不会改变对另一种方法的影响。


以下是两者的区别:

enter image description here

enter image description here

下面是一个逐步分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
A = ['spam']
"A points to a list whose first element, or A[0], is 'spam'."
B = A
"B points to what A points to, which is the same list."
B[0] = 'shrubbery'
"When we set B[0] to 'shrubbery', the result can be observed in the diagram.
A[0] is set to 'shrubbery' as well."

print (A):



A = 'string'
"A points to 'string'."
B = A
"B points to what A points to, which is 'string'."
B = 'dog'
"Oh look! B points to another string, 'dog', now.
So does what A points to change? No."

The result can be observed in the diagram.
print (A):