测试知识:答案
-
考虑下面三个语句。它们有没有改变A打印的值?
A = "spam" B = A B = "shrubbery"
没有:A 仍然打印为 "spam". 当B被赋值为字符串"shrubbery"时,所有发生的是变量B被重置来指向新的字符串对象。A和B一开始共享(即,引用/指向)同样的单字符串对象”spam“,但在Python中这两个名称从未相互链接。因此,设定B为不同对象对A是无效的。顺便说一下,如果这里最后语句是
B = B + 'shrubbery'
,结果是一样的——连接操作会为其结果产生新的对象,它将会只赋值给B。永远不能就地覆盖一个字符串(或数字,或元组),因为字符串是不可改变的。 -
考虑下面三个语句。它们有没有改变A打印的值?
A = ["spam"] B = A B[0] = "shrubbery"
有:A 现在打印为 ["shrubbery"]。技术上讲,没有真正改变A或B;相反,通过经变量B就地覆盖它们都引用(指向)的对象,改变了那个对象的一部分。因为A引用和B引用的同样对象,因此更新在A中也反应了出来。
-
这些呢——现在A有改变吗?
A = ["spam"] B = A[:] B[0] = "shrubbery"
没有:A仍然打印为["spam"]。通过B的就地赋值这次没有效果,因为在列表对象被赋值给B前,切片表达式创建了列表对象的一个拷贝。在第二个赋值语句后,有两个不同的列表对象有同样的值(在Python中,我们说它们是==,但不是
is
)。第三个语句改变了被B指向的列表对象的值,但并没有改变被A指向的那个对象的值。