python引用

正如你看到的,变量保存字符串和整数值。在交互式环境中输入以下代码:

>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42

你将 42 赋给 spam 变量,然后拷贝 spam 中的值,将它赋给变量 cheese。当稍后将 spam中的值改变为 100 时,这不会影响cheese中的值。这是因为 spam和 cheese是不同的变量,保存了不同的值。但列表不是这样的。当你将列表赋给一个变量时,实际上是将列表的“引用”赋给了该变量。引用是一个值,指向某些数据。列表引用是指向一个列表的值。这里有一些代码,让这个概念更容易理解。在交互式环境中输入以下代码:

>>> spam = [0, 1, 2, 3, 4, 5]
>>> cheese = spam
>>> cheese[1] = 'Hello!'
>>> spam
[0, 'Hello!', 2, 3, 4, 5]
>>> cheese
[0, 'Hello!', 2, 3, 4, 5]

这可能让你感到奇怪。代码只改变了 cheese 列表,但似乎 cheese 和 spam 列表同时发生了改变。当创建列表时,你将对它的引用赋给了变量。但下一行只是将 spam 中的列表引用拷贝到 cheese,而不是列表值本身。这意味着存储在 spam 和 cheese 中的值,现在指向了同一个列表。底下只有一个列表,因为列表本身实际从未复制。所以当你修改 cheese 变量的第一个元素时,也修改了 spam 指向的同一个列表。记住,变量就像包含着值的盒子。本章前面的图显示列表在盒子中,这并不准确,因为列表变量实际上没有包含列表,而是包含了对列表的“引用”(这些引用包含一些 ID 数字,Python 在内部使用这些 ID,但是你可以忽略)。利用盒子作为变量的隐喻,图 4-4 展示了列表被赋给 spam 变量时发生的情形。


图 4-4     spam = [0, 1, 2, 3, 4, 5]保存了对列表的引用,而非实际列表

然后,在图 4-5 中,spam 中的引用被复制给 cheese。只有新的引用被创建并保存在 cheese 中,而非新的列表。请注意,两个引用都指向同一个列表。

当你改变 cheese 指向的列表时,spam 指向的列表也发生了改变,因为 cheese和 spam 都指向同一个列表,如图 4-6 所示。

变量包含对列表值的引用,而不是列表值本身。但对于字符串和整数值,变量就包含了字符串或整数值。在变量必须保存可变数据类型的值时,例如列表或字典,Python 就使用引用。对于不可变的数据类型的值,例如字符串、整型或元组,Python变量就保存值本身。虽然 Python 变量在技术上包含了对列表或字典值的引用,但人们通常随意地说,该变量包含了列表或字典。

猜你喜欢

转载自blog.csdn.net/dongyu1703/article/details/81584491