使用Python 3.4并通过O'Reily的书中的示例进行操作。该示例显示:
A = ['spam']
B = A
B[0] = 'shrubbery'
运行print A
后的结果:
'shrubbery'
现在我的思维过程是定义了A
但从未改变过。
此示例产生不同的结果
A = 'string'
B = A
B = 'dog'
这是运行print A
后的结果:
'string'
谁能解释一下?
在第一个示例中,您正在修改B
引用的列表。
这样做:
B[0] = 'shrubbery'
告诉Python将B
引用的列表中的第一个项设置为'shrubbery'
的值。此外,此列表恰好与A
引用的列表相同。这是因为做:
B = A
导致B
和A
每个引用相同的列表:
>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>
因此,B
引用的列表的任何更改也会影响A
引用的列表(反之亦然),因为它们是同一个对象。
然而,第二个例子没有修改任何东西。相反,它只是将名称B
重新指定为新值。
执行此行后:
B = 'dog'
B
不再引用字符串'string'
而是引用新字符串'dog'
。与此同时,A
的价值保持不变。
与大多数现代动态语言中的情况一样,python中的变量实际上是类似C指针的引用。这意味着当你执行类似A = B
(其中A和B都是变量)的操作时,只需将A指向内存中与B相同的位置即可。
在第一个示例中,您正在改变(修改)现有对象 - 这就是variable_name[index/key] = value
语法的作用。 A和B都继续指出同样的事情,但这件事第一次进入现在是“灌木丛”,而不是“垃圾邮件”。
在第二个示例中,当您说B = 'dog'
时,您将B点指向另一个(此时为new)对象。
我希望你能用这种方式理解它:-)
正如你在第一种方法中看到的那样,它们都指向相同的list
,第二种不同。所以第二种方式不会改变对另一种方式的影响。
可变对象是列表,而字符串是不可变的,这就是为什么你可以改变内存地址和列表本身而不是字符串。
以下是两者之间的差异:
这是一步一步的分析:
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):