这一问题O' Reilly出版的"Learning Python" 2nd Edition的 13.4 节有专门论述,对于不可变(immutabe)对象,函数参数(这里是x和y)只是函数(这里是change)名字空间里对象(这里是0和[3,4])的一个新名字,当x=1时,x指向了一个新对象,外层的X与0之间的引用关系不受影响,类似于Pascal的 “值传递”,对于可变(mutable)对象,由于不存在重新赋值,因此函数内部对y一部分的改变使外层的k也发生了变化,类似于Pascal的“引用传递”了。如果希望对可变对象使用“值传递”,就得在调用过程中创造一个“副本”,这样函数内部对副本的修改就不会影响原件了。 用一个例子说明, 首先是引用传递版本 :
def change(x,y):
x = 1
y[0] = 'aa'
X = 0
k = [3,4]
change(X,k)
print X,k
#output: 0 ['aa', 4]
然后是“值传递”版本:
def change(x,y):
x = 1
y[0] = 'aa'
X = 0
k = [3,4]
change(X,k [:] )
print X
print k
#output: 0 [3, 4]
为什么k[:]是k的副本呢?"Learning Python"的 7.5 节解释说“Slice expressions with empty limits copy sequences”,就是说k[:]是首先取出k所有元素组成一个sequence,然后将这个sequence转换成一个新的list,所以k[:]和k是不相关的。