测试知识:答案
-
考虑下面三个语句。它们有没有改变 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 指向的那个对象的值。