代码段一:
代码段1
>>>a=6
>>>b=a
>>>a,b
输出:
(6,6)
上述代码段一中,第一行我们创建了对象6,并将变量a与之相关联,第二行代码中创建了变量b,变量b是对象6的一个引用。此时,变量a和变量b都引用了相同的对象,都指向了相同的内存空间。这种现象在Python语言中叫做共享引用——多个变量名引用同一对象。
代码段二:
代码段2
>>>a=6
>>>b=a
>>>a='six'
>>>a,b
输出:
('six',6)
这里第三行代码创建了一个新的对象‘six’,并让变量a引用了对象‘six’,而变量b则继续引用之前的对象6.
与其他编程语言不同,在Python中,给一个变量赋一个新的值,并不是替换原始对象,而是重建一个不同的对象,并让这个变量去引用这个新的对象。实际效果就是,对一个变量赋值,仅仅会影响被赋值的变量。
但是,也有一些特殊的情况,当引用一些可变对象时,在原处对对象进行修改时,就会出现不一样的情况。例如,在一个列表中对某一个偏移位置进行重新赋值时,会改变这个列表对象,而不是生成一个新的对象。来看代码段三。
代码段三:
代码段3
>>>a=[1,2,3]
>>>b=a
>>>a
输出:
[1,2,3]
>>>b
输出:
[1,2,3]
>>>a=999
>>>a
输出:
999
>>>b
输出:
[1,2,3]
这里一开始变量a和变量b都引用了列表对象[1,2,3],后来当对重新赋值后,创建了对象999,并让变量a引用了这个新对象,整个过程中变量b并没有发生变化,这与前面的代码段类似,都属于共享引用的范畴。
然而,列表中元素都是通过其索引位置进行读取的,例如
>>>a=[1,2,3]
>>>b=a
>>>a[0],a[1],a[2]
输出:
(1,2,3)
其中,a[0]引用对象1,a[1]引用对象2,a[2]引用对象3.当然,列表自身也是一个对象,接下来对上述代码做简单的变化,就会出现不同的效果。
代码段五:
代码段5
>>>a=[1,2,3] # 创建列表对象[1,2,3]和变量a,并让变量a引用该对象
>>>b=a # 创建变量b,并让变量b引用同一列表对象
>>>a
输出:
[1,2,3]
>>>b
输出:
[1,2,3] # 到这里,变量a和变量b值相同
>>>a[0]='one' # 修改变量所引用对象的一个元素
>>>a
输出:
['one',2,3] # 变量a数值发生变化
>>>b
输出:
['one',2,3] # 变量b数值发生变化
在代码段5中,我们没有改变a,只是改变了a所引用对象的一个元素,这类修改会覆盖对象中的某些部分,它不仅仅会影响变量a,也会影响变量b,因为他们引用的是同一个列表对象。因此在使用共享引用时要特别小心。
如果不希望出现上述情况,可以使用Python的对象复制,而不是创建引用。Python的复制列表方法有很多。
>>>a=[1,2,3]
>>>b=a[:] # 复制列表
# 或者也可以使用cope函数
>>>import copy
>>>a=[1,2,3]
>>>b=copy.copy(a) # 复制列表